Replacing Brillo Error

Creating our own error struct to remove libchrome dependancy. This also
allows us to propogate the error up and send more useful error messages

Test: m update_engine
Change-Id: I1bb651d9b7e759c9f902590685c1910b97c4ab5d
diff --git a/aosp/binder_service_android.cc b/aosp/binder_service_android.cc
index 84b5b7a..e7c20c5 100644
--- a/aosp/binder_service_android.cc
+++ b/aosp/binder_service_android.cc
@@ -21,7 +21,6 @@
 #include <base/bind.h>
 #include <base/logging.h>
 #include <binderwrapper/binder_wrapper.h>
-#include <brillo/errors/error.h>
 #include <utils/String8.h>
 
 #include "update_engine/aosp/binder_service_android_common.h"
@@ -106,7 +105,7 @@
   const string payload_url{android::String8{url}.string()};
   vector<string> str_headers = ToVecString(header_kv_pairs);
 
-  brillo::ErrorPtr error;
+  Error error;
   if (!service_delegate_->ApplyPayload(
           payload_url, payload_offset, payload_size, str_headers, &error)) {
     return ErrorPtrToStatus(error);
@@ -121,7 +120,7 @@
     const vector<android::String16>& header_kv_pairs) {
   vector<string> str_headers = ToVecString(header_kv_pairs);
 
-  brillo::ErrorPtr error;
+  Error error;
   if (!service_delegate_->ApplyPayload(
           pfd.get(), payload_offset, payload_size, str_headers, &error)) {
     return ErrorPtrToStatus(error);
@@ -130,28 +129,28 @@
 }
 
 Status BinderUpdateEngineAndroidService::suspend() {
-  brillo::ErrorPtr error;
+  Error error;
   if (!service_delegate_->SuspendUpdate(&error))
     return ErrorPtrToStatus(error);
   return Status::ok();
 }
 
 Status BinderUpdateEngineAndroidService::resume() {
-  brillo::ErrorPtr error;
+  Error error;
   if (!service_delegate_->ResumeUpdate(&error))
     return ErrorPtrToStatus(error);
   return Status::ok();
 }
 
 Status BinderUpdateEngineAndroidService::cancel() {
-  brillo::ErrorPtr error;
+  Error error;
   if (!service_delegate_->CancelUpdate(&error))
     return ErrorPtrToStatus(error);
   return Status::ok();
 }
 
 Status BinderUpdateEngineAndroidService::resetStatus() {
-  brillo::ErrorPtr error;
+  Error error;
   if (!service_delegate_->ResetStatus(&error))
     return ErrorPtrToStatus(error);
   return Status::ok();
@@ -159,7 +158,7 @@
 
 Status BinderUpdateEngineAndroidService::setShouldSwitchSlotOnReboot(
     const android::String16& metadata_filename) {
-  brillo::ErrorPtr error;
+  Error error;
   if (!service_delegate_->setShouldSwitchSlotOnReboot(
           android::String8(metadata_filename).string(), &error)) {
     return ErrorPtrToStatus(error);
@@ -168,7 +167,7 @@
 }
 
 Status BinderUpdateEngineAndroidService::resetShouldSwitchSlotOnReboot() {
-  brillo::ErrorPtr error;
+  Error error;
   if (!service_delegate_->resetShouldSwitchSlotOnReboot(&error)) {
     return ErrorPtrToStatus(error);
   }
@@ -181,10 +180,10 @@
       android::String8{metadata_filename}.string()};
   LOG(INFO) << "Received a request of verifying payload metadata in "
             << payload_metadata << ".";
-  brillo::ErrorPtr error;
+  Error error;
   *return_value =
       service_delegate_->VerifyPayloadApplicable(payload_metadata, &error);
-  if (error != nullptr)
+  if (error.error_code != ErrorCode::kSuccess)
     return ErrorPtrToStatus(error);
   return Status::ok();
 }
@@ -213,11 +212,11 @@
   vector<string> str_headers = ToVecString(header_kv_pairs);
   LOG(INFO) << "Received a request of allocating space for " << payload_metadata
             << ".";
-  brillo::ErrorPtr error;
+  Error error;
   *return_value =
       static_cast<int64_t>(service_delegate_->AllocateSpaceForPayload(
           payload_metadata, str_headers, &error));
-  if (error != nullptr)
+  if (error.error_code != ErrorCode::kSuccess)
     return ErrorPtrToStatus(error);
   return Status::ok();
 }
@@ -250,10 +249,10 @@
 
 Status BinderUpdateEngineAndroidService::cleanupSuccessfulUpdate(
     const android::sp<IUpdateEngineCallback>& callback) {
-  brillo::ErrorPtr error;
+  Error error;
   service_delegate_->CleanupSuccessfulUpdate(
       std::make_unique<CleanupSuccessfulUpdateCallback>(callback), &error);
-  if (error != nullptr)
+  if (error.error_code != ErrorCode::kSuccess)
     return ErrorPtrToStatus(error);
   return Status::ok();
 }
diff --git a/aosp/binder_service_android_common.h b/aosp/binder_service_android_common.h
index 5e137b9..eb3588d 100644
--- a/aosp/binder_service_android_common.h
+++ b/aosp/binder_service_android_common.h
@@ -20,16 +20,16 @@
 #include <string>
 #include <vector>
 
-#include "brillo/errors/error.h"
+#include "update_engine/common/error.h"
 
 #include <binder/Status.h>
 
 namespace chromeos_update_engine {
 
-static inline android::binder::Status ErrorPtrToStatus(
-    const brillo::ErrorPtr& error) {
+static inline android::binder::Status ErrorPtrToStatus(const Error& error) {
   return android::binder::Status::fromServiceSpecificError(
-      1, android::String8{error->GetMessage().c_str()});
+      static_cast<int>(error.error_code),
+      android::String8{error.message.c_str()});
 }
 
 static inline std::vector<std::string> ToVecString(
diff --git a/aosp/binder_service_stable_android.cc b/aosp/binder_service_stable_android.cc
index 17b35ee..9a9969d 100644
--- a/aosp/binder_service_stable_android.cc
+++ b/aosp/binder_service_stable_android.cc
@@ -21,7 +21,6 @@
 #include <base/bind.h>
 #include <base/logging.h>
 #include <binderwrapper/binder_wrapper.h>
-#include <brillo/errors/error.h>
 #include <utils/String8.h>
 
 #include "update_engine/aosp/binder_service_android_common.h"
@@ -111,7 +110,7 @@
     const vector<android::String16>& header_kv_pairs) {
   vector<string> str_headers = ToVecString(header_kv_pairs);
 
-  brillo::ErrorPtr error;
+  Error error;
   if (!service_delegate_->ApplyPayload(
           pfd.get(), payload_offset, payload_size, str_headers, &error)) {
     return ErrorPtrToStatus(error);
diff --git a/aosp/service_delegate_android_interface.h b/aosp/service_delegate_android_interface.h
index b3660ab..981689d 100644
--- a/aosp/service_delegate_android_interface.h
+++ b/aosp/service_delegate_android_interface.h
@@ -23,7 +23,8 @@
 #include <string>
 #include <vector>
 
-#include <brillo/errors/error.h>
+#include "base/callback_forward.h"
+#include "common/error.h"
 
 namespace chromeos_update_engine {
 
@@ -58,54 +59,54 @@
       int64_t payload_offset,
       int64_t payload_size,
       const std::vector<std::string>& key_value_pair_headers,
-      brillo::ErrorPtr* error) = 0;
+      Error* error) = 0;
 
   virtual bool ApplyPayload(
       int fd,
       int64_t payload_offset,
       int64_t payload_size,
       const std::vector<std::string>& key_value_pair_headers,
-      brillo::ErrorPtr* error) = 0;
+      Error* error) = 0;
 
   // Suspend an ongoing update. Returns true if there was an update ongoing and
   // it was suspended. In case of failure, it returns false and sets |error|
   // accordingly.
-  virtual bool SuspendUpdate(brillo::ErrorPtr* error) = 0;
+  virtual bool SuspendUpdate(Error* error) = 0;
 
   // Resumes an update suspended with SuspendUpdate(). The update can't be
   // suspended after it finished and this method will fail in that case.
   // Returns whether the resume operation was successful, which only implies
   // that there was a suspended update. In case of error, returns false and sets
   // |error| accordingly.
-  virtual bool ResumeUpdate(brillo::ErrorPtr* error) = 0;
+  virtual bool ResumeUpdate(Error* error) = 0;
 
   // Cancel the ongoing update. The update could be running or suspended, but it
   // can't be canceled after it was done. In case of error, returns false and
   // sets |error| accordingly.
-  virtual bool CancelUpdate(brillo::ErrorPtr* error) = 0;
+  virtual bool CancelUpdate(Error* error) = 0;
 
   // Reset the already applied update back to an idle state. This method can
   // only be called when no update attempt is going on, and it will reset the
   // status back to idle, deleting the currently applied update if any. In case
   // of error, returns false and sets |error| accordingly.
-  virtual bool ResetStatus(brillo::ErrorPtr* error) = 0;
+  virtual bool ResetStatus(Error* error) = 0;
 
   // Verifies whether a payload (delegated by the payload metadata) can be
   // applied to the current device. Returns whether the payload is applicable.
   // In case of error, returns false and sets |error| accordingly.
   virtual bool VerifyPayloadApplicable(const std::string& metadata_filename,
-                                       brillo::ErrorPtr* error) = 0;
+                                       Error* error) = 0;
   // Sets the A/B slot switch for the next boot after applying an ota update.
   // If applyPayload hasn't switched the slot by itself, the client can call
   // this API to switch the slot and apply the update on next boot. Returns
   // true on success.
   virtual bool setShouldSwitchSlotOnReboot(const std::string& metadata_filename,
-                                           brillo::ErrorPtr* error) = 0;
+                                           Error* error) = 0;
 
   // Resets the boot slot to the source/current slot, without cancelling the
   // update progress. This can be called after the update is installed, and to
   // prevent the device from accidentally taking the update when it reboots.
-  virtual bool resetShouldSwitchSlotOnReboot(brillo::ErrorPtr* error) = 0;
+  virtual bool resetShouldSwitchSlotOnReboot(Error* error) = 0;
 
   // Allocates space for a payload.
   // Returns 0 if space is successfully preallocated.
@@ -118,7 +119,7 @@
   virtual uint64_t AllocateSpaceForPayload(
       const std::string& metadata_filename,
       const std::vector<std::string>& key_value_pair_headers,
-      brillo::ErrorPtr* error) = 0;
+      Error* error) = 0;
 
   // Wait for merge to complete, then clean up merge after an update has been
   // successful.
@@ -127,7 +128,7 @@
   // |callback|.
   virtual void CleanupSuccessfulUpdate(
       std::unique_ptr<CleanupSuccessfulUpdateCallbackInterface> callback,
-      brillo::ErrorPtr* error) = 0;
+      Error* error) = 0;
 
  protected:
   ServiceDelegateAndroidInterface() = default;
diff --git a/aosp/update_attempter_android.cc b/aosp/update_attempter_android.cc
index 6134885..2e0232b 100644
--- a/aosp/update_attempter_android.cc
+++ b/aosp/update_attempter_android.cc
@@ -81,18 +81,32 @@
 const double kBroadcastThresholdProgress = 0.01;  // 1%
 const int kBroadcastThresholdSeconds = 10;
 
-const char* const kErrorDomain = "update_engine";
-// TODO(deymo): Convert the different errors to a numeric value to report them
-// back on the service error.
-const char* const kGenericError = "generic_error";
+// Log and set the error on the passed ErrorPtr.
+bool LogAndSetGenericError(Error* error,
+                           int line_number,
+                           const char* file_name,
+                           const string& reason) {
+  LOG(ERROR) << "Replying with failure: " << file_name << " " << line_number
+             << ": " << reason;
+  error->line_number = line_number;
+  error->file_name = file_name;
+  error->message = reason;
+  error->error_code = ErrorCode::kError;
+  return false;
+}
 
 // Log and set the error on the passed ErrorPtr.
-bool LogAndSetError(brillo::ErrorPtr* error,
-                    const base::Location& location,
-                    const string& reason) {
-  brillo::Error::AddTo(error, location, kErrorDomain, kGenericError, reason);
-  LOG(ERROR) << "Replying with failure: " << location.ToString() << ": "
-             << reason;
+bool LogAndSetError(Error* error,
+                    int line_number,
+                    const char* file_name,
+                    const string& reason,
+                    ErrorCode error_code) {
+  LOG(ERROR) << "Replying with failure: " << file_name << " " << line_number
+             << ": " << reason;
+  error->line_number = line_number;
+  error->file_name = file_name;
+  error->message = reason;
+  error->error_code = error_code;
   return false;
 }
 
@@ -105,17 +119,20 @@
 
 bool ParseKeyValuePairHeaders(const vector<string>& key_value_pair_headers,
                               std::map<string, string>* headers,
-                              brillo::ErrorPtr* error) {
+                              Error* error) {
   for (const string& key_value_pair : key_value_pair_headers) {
     string key;
     string value;
     if (!brillo::string_utils::SplitAtFirst(
             key_value_pair, "=", &key, &value, false)) {
-      return LogAndSetError(
-          error, FROM_HERE, "Passed invalid header: " + key_value_pair);
+      return LogAndSetGenericError(error,
+                                   __LINE__,
+                                   __FILE__,
+                                   "Passed invalid header: " + key_value_pair);
     }
     if (!headers->emplace(key, value).second)
-      return LogAndSetError(error, FROM_HERE, "Passed repeated key: " + key);
+      return LogAndSetGenericError(
+          error, __LINE__, __FILE__, "Passed repeated key: " + key);
   }
   return true;
 }
@@ -217,14 +234,20 @@
     int64_t payload_offset,
     int64_t payload_size,
     const vector<string>& key_value_pair_headers,
-    brillo::ErrorPtr* error) {
+    Error* error) {
   if (status_ == UpdateStatus::UPDATED_NEED_REBOOT) {
-    return LogAndSetError(
-        error, FROM_HERE, "An update already applied, waiting for reboot");
+    return LogAndSetGenericError(
+        error,
+        __LINE__,
+        __FILE__,
+        "An update already applied, waiting for reboot");
   }
   if (processor_->IsRunning()) {
-    return LogAndSetError(
-        error, FROM_HERE, "Already processing an update, cancel it first.");
+    return LogAndSetGenericError(
+        error,
+        __LINE__,
+        __FILE__,
+        "Already processing an update, cancel it first.");
   }
   DCHECK_EQ(status_, UpdateStatus::IDLE);
 
@@ -307,15 +330,17 @@
   if (!headers[kPayloadPropertyNetworkId].empty()) {
     if (!base::StringToUint64(headers[kPayloadPropertyNetworkId],
                               &network_id)) {
-      return LogAndSetError(
+      return LogAndSetGenericError(
           error,
-          FROM_HERE,
+          __LINE__,
+          __FILE__,
           "Invalid network_id: " + headers[kPayloadPropertyNetworkId]);
     }
     if (!network_selector_->SetProcessNetwork(network_id)) {
-      return LogAndSetError(
+      return LogAndSetGenericError(
           error,
-          FROM_HERE,
+          __LINE__,
+          __FILE__,
           "Unable to set network_id: " + headers[kPayloadPropertyNetworkId]);
     }
   }
@@ -379,17 +404,23 @@
     int64_t payload_offset,
     int64_t payload_size,
     const vector<string>& key_value_pair_headers,
-    brillo::ErrorPtr* error) {
+    Error* error) {
   // update_engine state must be checked before modifying payload_fd_ otherwise
   // already running update will be terminated (existing file descriptor will be
   // closed)
   if (status_ == UpdateStatus::UPDATED_NEED_REBOOT) {
-    return LogAndSetError(
-        error, FROM_HERE, "An update already applied, waiting for reboot");
+    return LogAndSetGenericError(
+        error,
+        __LINE__,
+        __FILE__,
+        "An update already applied, waiting for reboot");
   }
   if (processor_->IsRunning()) {
-    return LogAndSetError(
-        error, FROM_HERE, "Already processing an update, cancel it first.");
+    return LogAndSetGenericError(
+        error,
+        __LINE__,
+        __FILE__,
+        "Already processing an update, cancel it first.");
   }
   DCHECK_EQ(status_, UpdateStatus::IDLE);
 
@@ -400,40 +431,48 @@
       payload_url, payload_offset, payload_size, key_value_pair_headers, error);
 }
 
-bool UpdateAttempterAndroid::SuspendUpdate(brillo::ErrorPtr* error) {
+bool UpdateAttempterAndroid::SuspendUpdate(Error* error) {
   if (!processor_->IsRunning())
-    return LogAndSetError(error, FROM_HERE, "No ongoing update to suspend.");
+    return LogAndSetGenericError(
+        error, __LINE__, __FILE__, "No ongoing update to suspend.");
   processor_->SuspendProcessing();
   return true;
 }
 
-bool UpdateAttempterAndroid::ResumeUpdate(brillo::ErrorPtr* error) {
+bool UpdateAttempterAndroid::ResumeUpdate(Error* error) {
   if (!processor_->IsRunning())
-    return LogAndSetError(error, FROM_HERE, "No ongoing update to resume.");
+    return LogAndSetGenericError(
+        error, __LINE__, __FILE__, "No ongoing update to resume.");
   processor_->ResumeProcessing();
   return true;
 }
 
-bool UpdateAttempterAndroid::CancelUpdate(brillo::ErrorPtr* error) {
+bool UpdateAttempterAndroid::CancelUpdate(Error* error) {
   if (!processor_->IsRunning())
-    return LogAndSetError(error, FROM_HERE, "No ongoing update to cancel.");
+    return LogAndSetGenericError(
+        error, __LINE__, __FILE__, "No ongoing update to cancel.");
   processor_->StopProcessing();
   return true;
 }
 
-bool UpdateAttempterAndroid::ResetStatus(brillo::ErrorPtr* error) {
+bool UpdateAttempterAndroid::ResetStatus(Error* error) {
   LOG(INFO) << "Attempting to reset state from "
             << UpdateStatusToString(status_) << " to UpdateStatus::IDLE";
   if (processor_->IsRunning()) {
-    return LogAndSetError(
-        error, FROM_HERE, "Already processing an update, cancel it first.");
+    return LogAndSetGenericError(
+        error,
+        __LINE__,
+        __FILE__,
+        "Already processing an update, cancel it first.");
   }
   if (status_ != UpdateStatus::IDLE &&
       status_ != UpdateStatus::UPDATED_NEED_REBOOT) {
-    return LogAndSetError(error,
-                          FROM_HERE,
-                          "Status reset not allowed in this state, please "
-                          "cancel on going OTA first.");
+    return LogAndSetGenericError(
+        error,
+        __LINE__,
+        __FILE__,
+        "Status reset not allowed in this state, please "
+        "cancel on going OTA first.");
   }
 
   if (apex_handler_android_ != nullptr) {
@@ -445,10 +484,11 @@
   // after resetting to idle state, it doesn't go back to
   // UpdateStatus::UPDATED_NEED_REBOOT state.
   if (!ClearUpdateCompletedMarker()) {
-    return LogAndSetError(error,
-                          FROM_HERE,
-                          "Failed to reset the status because "
-                          "ClearUpdateCompletedMarker() failed");
+    return LogAndSetGenericError(error,
+                                 __LINE__,
+                                 __FILE__,
+                                 "Failed to reset the status because "
+                                 "ClearUpdateCompletedMarker() failed");
   }
   if (status_ == UpdateStatus::UPDATED_NEED_REBOOT) {
     if (!resetShouldSwitchSlotOnReboot(error)) {
@@ -478,27 +518,34 @@
     const std::string& metadata_filename,
     std::string_view expected_metadata_hash,
     DeltaArchiveManifest* manifest,
-    brillo::ErrorPtr* error) {
+    Error* error) {
   FileDescriptorPtr fd(new EintrSafeFileDescriptor);
   if (!fd->Open(metadata_filename.c_str(), O_RDONLY)) {
-    return LogAndSetError(
-        error, FROM_HERE, "Failed to open " + metadata_filename);
+    return LogAndSetError(error,
+                          __LINE__,
+                          __FILE__,
+                          "Failed to open " + metadata_filename,
+                          ErrorCode::kDownloadManifestParseError);
   }
   brillo::Blob metadata(kMaxPayloadHeaderSize);
   if (!fd->Read(metadata.data(), metadata.size())) {
     return LogAndSetError(
         error,
-        FROM_HERE,
-        "Failed to read payload header from " + metadata_filename);
+        __LINE__,
+        __FILE__,
+        "Failed to read payload header from " + metadata_filename,
+        ErrorCode::kDownloadManifestParseError);
   }
   ErrorCode errorcode{};
   PayloadMetadata payload_metadata;
   if (payload_metadata.ParsePayloadHeader(metadata, &errorcode) !=
       MetadataParseResult::kSuccess) {
     return LogAndSetError(error,
-                          FROM_HERE,
+                          __LINE__,
+                          __FILE__,
                           "Failed to parse payload header: " +
-                              utils::ErrorCodeToString(errorcode));
+                              utils::ErrorCodeToString(errorcode),
+                          errorcode);
   }
   uint64_t metadata_size = payload_metadata.GetMetadataSize() +
                            payload_metadata.GetMetadataSignatureSize();
@@ -507,16 +554,20 @@
           static_cast<uint64_t>(utils::FileSize(metadata_filename))) {
     return LogAndSetError(
         error,
-        FROM_HERE,
-        "Invalid metadata size: " + std::to_string(metadata_size));
+        __LINE__,
+        __FILE__,
+        "Invalid metadata size: " + std::to_string(metadata_size),
+        ErrorCode::kDownloadManifestParseError);
   }
   metadata.resize(metadata_size);
   if (!fd->Read(metadata.data() + kMaxPayloadHeaderSize,
                 metadata.size() - kMaxPayloadHeaderSize)) {
     return LogAndSetError(
         error,
-        FROM_HERE,
-        "Failed to read metadata and signature from " + metadata_filename);
+        __LINE__,
+        __FILE__,
+        "Failed to read metadata and signature from " + metadata_filename,
+        ErrorCode::kDownloadManifestParseError);
   }
   fd->Close();
   if (!expected_metadata_hash.empty()) {
@@ -525,10 +576,12 @@
         metadata.data(), payload_metadata.GetMetadataSize(), &metadata_hash));
     if (metadata_hash != expected_metadata_hash) {
       return LogAndSetError(error,
-                            FROM_HERE,
+                            __LINE__,
+                            __FILE__,
                             "Metadata hash mismatch. Expected hash: " +
                                 HexEncode(expected_metadata_hash) +
-                                " actual hash: " + HexEncode(metadata_hash));
+                                " actual hash: " + HexEncode(metadata_hash),
+                            ErrorCode::kDownloadManifestParseError);
     } else {
       LOG(INFO) << "Payload metadata hash check passed : "
                 << HexEncode(metadata_hash);
@@ -539,27 +592,35 @@
       constants::kUpdateCertificatesPath);
   if (!payload_verifier) {
     return LogAndSetError(error,
-                          FROM_HERE,
+                          __LINE__,
+                          __FILE__,
                           "Failed to create the payload verifier from " +
-                              std::string(constants::kUpdateCertificatesPath));
+                              std::string(constants::kUpdateCertificatesPath),
+                          ErrorCode::kDownloadManifestParseError);
   }
   errorcode = payload_metadata.ValidateMetadataSignature(
       metadata, "", *payload_verifier);
   if (errorcode != ErrorCode::kSuccess) {
     return LogAndSetError(error,
-                          FROM_HERE,
+                          __LINE__,
+                          __FILE__,
                           "Failed to validate metadata signature: " +
-                              utils::ErrorCodeToString(errorcode));
+                              utils::ErrorCodeToString(errorcode),
+                          errorcode);
   }
   if (!payload_metadata.GetManifest(metadata, manifest)) {
-    return LogAndSetError(error, FROM_HERE, "Failed to parse manifest.");
+    return LogAndSetError(error,
+                          __LINE__,
+                          __FILE__,
+                          "Failed to parse manifest.",
+                          ErrorCode::kDownloadManifestParseError);
   }
 
   return true;
 }
 
 bool UpdateAttempterAndroid::VerifyPayloadApplicable(
-    const std::string& metadata_filename, brillo::ErrorPtr* error) {
+    const std::string& metadata_filename, Error* error) {
   DeltaArchiveManifest manifest;
   TEST_AND_RETURN_FALSE(
       VerifyPayloadParseManifest(metadata_filename, &manifest, error));
@@ -574,14 +635,15 @@
     string partition_path;
     if (!boot_control_->GetPartitionDevice(
             partition.partition_name(), current_slot, &partition_path)) {
-      return LogAndSetError(
+      return LogAndSetGenericError(
           error,
-          FROM_HERE,
+          __LINE__,
+          __FILE__,
           "Failed to get partition device for " + partition.partition_name());
     }
     if (!fd->Open(partition_path.c_str(), O_RDONLY)) {
-      return LogAndSetError(
-          error, FROM_HERE, "Failed to open " + partition_path);
+      return LogAndSetGenericError(
+          error, __LINE__, __FILE__, "Failed to open " + partition_path);
     }
     for (const InstallOperation& operation : partition.operations()) {
       if (!operation.has_src_sha256_hash())
@@ -591,8 +653,8 @@
                                         operation.src_extents(),
                                         manifest.block_size(),
                                         &source_hash)) {
-        return LogAndSetError(
-            error, FROM_HERE, "Failed to hash " + partition_path);
+        return LogAndSetGenericError(
+            error, __LINE__, __FILE__, "Failed to hash " + partition_path);
       }
       if (!PartitionWriter::ValidateSourceHash(
               source_hash, operation, fd, &errorcode)) {
@@ -1122,7 +1184,7 @@
 uint64_t UpdateAttempterAndroid::AllocateSpaceForPayload(
     const std::string& metadata_filename,
     const vector<string>& key_value_pair_headers,
-    brillo::ErrorPtr* error) {
+    Error* error) {
   std::map<string, string> headers;
   if (!ParseKeyValuePairHeaders(key_value_pair_headers, &headers, error)) {
     return 0;
@@ -1144,9 +1206,11 @@
   if (apex_handler_android_ != nullptr) {
     auto result = apex_handler_android_->CalculateSize(apex_infos);
     if (!result.ok()) {
-      LogAndSetError(error,
-                     FROM_HERE,
-                     "Failed to calculate size required for compressed APEX");
+      LogAndSetGenericError(
+          error,
+          __LINE__,
+          __FILE__,
+          "Failed to calculate size required for compressed APEX");
       return 0;
     }
     apex_size_required = *result;
@@ -1161,7 +1225,8 @@
                                                   payload_id,
                                                   &required_size)) {
     if (required_size == 0) {
-      LogAndSetError(error, FROM_HERE, "Failed to allocate space for payload.");
+      LogAndSetGenericError(
+          error, __LINE__, __FILE__, "Failed to allocate space for payload.");
       return 0;
     } else {
       LOG(ERROR) << "Insufficient space for payload: " << required_size
@@ -1184,7 +1249,7 @@
 
 void UpdateAttempterAndroid::CleanupSuccessfulUpdate(
     std::unique_ptr<CleanupSuccessfulUpdateCallbackInterface> callback,
-    brillo::ErrorPtr* error) {
+    Error* error) {
   if (cleanup_previous_update_code_.has_value()) {
     LOG(INFO) << "CleanupSuccessfulUpdate has previously completed with "
               << utils::ErrorCodeToString(*cleanup_previous_update_code_);
@@ -1206,11 +1271,14 @@
 }
 
 bool UpdateAttempterAndroid::setShouldSwitchSlotOnReboot(
-    const std::string& metadata_filename, brillo::ErrorPtr* error) {
+    const std::string& metadata_filename, Error* error) {
   LOG(INFO) << "setShouldSwitchSlotOnReboot(" << metadata_filename << ")";
   if (processor_->IsRunning()) {
-    return LogAndSetError(
-        error, FROM_HERE, "Already processing an update, cancel it first.");
+    return LogAndSetGenericError(
+        error,
+        __LINE__,
+        __FILE__,
+        "Already processing an update, cancel it first.");
   }
   DeltaArchiveManifest manifest;
   TEST_AND_RETURN_FALSE(
@@ -1248,8 +1316,8 @@
                                           manifest,
                                           false /* should update */,
                                           nullptr)) {
-      return LogAndSetError(
-          error, FROM_HERE, "Failed to PreparePartitionsForUpdate");
+      return LogAndSetGenericError(
+          error, __LINE__, __FILE__, "Failed to PreparePartitionsForUpdate");
     }
     ErrorCode error_code{};
     if (!install_plan_.ParsePartitions(manifest.partitions(),
@@ -1257,9 +1325,11 @@
                                        manifest.block_size(),
                                        &error_code)) {
       return LogAndSetError(error,
-                            FROM_HERE,
+                            __LINE__,
+                            __FILE__,
                             "Failed to LoadPartitionsFromSlots " +
-                                utils::ErrorCodeToString(error_code));
+                                utils::ErrorCodeToString(error_code),
+                            error_code);
     }
 
     auto filesystem_verifier_action =
@@ -1278,24 +1348,27 @@
   return true;
 }
 
-bool UpdateAttempterAndroid::resetShouldSwitchSlotOnReboot(
-    brillo::ErrorPtr* error) {
+bool UpdateAttempterAndroid::resetShouldSwitchSlotOnReboot(Error* error) {
   if (processor_->IsRunning()) {
-    return LogAndSetError(
-        error, FROM_HERE, "Already processing an update, cancel it first.");
+    return LogAndSetGenericError(
+        error,
+        __LINE__,
+        __FILE__,
+        "Already processing an update, cancel it first.");
   }
   TEST_AND_RETURN_FALSE(ClearUpdateCompletedMarker());
   // Update the boot flags so the current slot has higher priority.
   if (!boot_control_->SetActiveBootSlot(GetCurrentSlot())) {
-    return LogAndSetError(error, FROM_HERE, "Failed to SetActiveBootSlot");
+    return LogAndSetGenericError(
+        error, __LINE__, __FILE__, "Failed to SetActiveBootSlot");
   }
 
   // Mark the current slot as successful again, since marking it as active
   // may reset the successful bit. We ignore the result of whether marking
   // the current slot as successful worked.
   if (!boot_control_->MarkBootSuccessfulAsync(Bind([](bool successful) {}))) {
-    return LogAndSetError(
-        error, FROM_HERE, "Failed to MarkBootSuccessfulAsync");
+    return LogAndSetGenericError(
+        error, __LINE__, __FILE__, "Failed to MarkBootSuccessfulAsync");
   }
 
   // Resets the warm reset property since we won't switch the slot.
diff --git a/aosp/update_attempter_android.h b/aosp/update_attempter_android.h
index bbffbe9..b7851f1 100644
--- a/aosp/update_attempter_android.h
+++ b/aosp/update_attempter_android.h
@@ -77,28 +77,28 @@
                     int64_t payload_offset,
                     int64_t payload_size,
                     const std::vector<std::string>& key_value_pair_headers,
-                    brillo::ErrorPtr* error) override;
+                    Error* error) override;
   bool ApplyPayload(int fd,
                     int64_t payload_offset,
                     int64_t payload_size,
                     const std::vector<std::string>& key_value_pair_headers,
-                    brillo::ErrorPtr* error) override;
-  bool SuspendUpdate(brillo::ErrorPtr* error) override;
-  bool ResumeUpdate(brillo::ErrorPtr* error) override;
-  bool CancelUpdate(brillo::ErrorPtr* error) override;
-  bool ResetStatus(brillo::ErrorPtr* error) override;
+                    Error* error) override;
+  bool SuspendUpdate(Error* error) override;
+  bool ResumeUpdate(Error* error) override;
+  bool CancelUpdate(Error* error) override;
+  bool ResetStatus(Error* error) override;
   bool VerifyPayloadApplicable(const std::string& metadata_filename,
-                               brillo::ErrorPtr* error) override;
+                               Error* error) override;
   uint64_t AllocateSpaceForPayload(
       const std::string& metadata_filename,
       const std::vector<std::string>& key_value_pair_headers,
-      brillo::ErrorPtr* error) override;
+      Error* error) override;
   void CleanupSuccessfulUpdate(
       std::unique_ptr<CleanupSuccessfulUpdateCallbackInterface> callback,
-      brillo::ErrorPtr* error) override;
+      Error* error) override;
   bool setShouldSwitchSlotOnReboot(const std::string& metadata_filename,
-                                   brillo::ErrorPtr* error) override;
-  bool resetShouldSwitchSlotOnReboot(brillo::ErrorPtr* error) override;
+                                   Error* error) override;
+  bool resetShouldSwitchSlotOnReboot(Error* error) override;
 
   // ActionProcessorDelegate methods:
   void ProcessingDone(const ActionProcessor* processor,
@@ -223,10 +223,10 @@
   static bool VerifyPayloadParseManifest(const std::string& metadata_filename,
                                          std::string_view metadata_hash,
                                          DeltaArchiveManifest* manifest,
-                                         brillo::ErrorPtr* error);
+                                         Error* error);
   static bool VerifyPayloadParseManifest(const std::string& metadata_filename,
                                          DeltaArchiveManifest* manifest,
-                                         brillo::ErrorPtr* error) {
+                                         Error* error) {
     return VerifyPayloadParseManifest(metadata_filename, "", manifest, error);
   }
 
diff --git a/aosp/update_attempter_android_integration_test.cc b/aosp/update_attempter_android_integration_test.cc
index 909aa3c..8f3bad7 100644
--- a/aosp/update_attempter_android_integration_test.cc
+++ b/aosp/update_attempter_android_integration_test.cc
@@ -36,6 +36,7 @@
 #include "update_engine/aosp/daemon_state_android.h"
 #include "update_engine/aosp/update_attempter_android.h"
 #include "update_engine/common/constants.h"
+#include "update_engine/common/error.h"
 #include "update_engine/common/fake_boot_control.h"
 #include "update_engine/common/fake_hardware.h"
 #include "update_engine/common/hash_calculator.h"
@@ -299,7 +300,7 @@
                                           &metadata_size));
     LOG(INFO) << "Signature offset: " << manifest->signatures_offset()
               << ", Signature size: " << manifest->signatures_size();
-    brillo::ErrorPtr error;
+    Error error;
     HashCalculator::RawHashOfFile(payload_file_.path(), &hash);
     daemon_state_.AddObserver(this);
     ASSERT_TRUE(update_attempter_android_.ApplyPayload(
@@ -311,10 +312,10 @@
              ("=" + brillo::data_encoding::Base64Encode(hash))},
         &error));
     brillo::MessageLoop::current()->Run();
-    if (error) {
-      LOG(ERROR) << error->GetMessage();
+    if (error.error_code != ErrorCode::kSuccess) {
+      LOG(ERROR) << error.message;
     }
-    ASSERT_EQ(error, nullptr);
+    ASSERT_EQ(error.error_code, ErrorCode::kSuccess) << error.message;
     ASSERT_EQ(completion_code_, ErrorCode::kSuccess);
   }
 
diff --git a/common/action_processor.h b/common/action_processor.h
index 6108c3e..5a4286f 100644
--- a/common/action_processor.h
+++ b/common/action_processor.h
@@ -22,7 +22,6 @@
 #include <vector>
 
 #include <base/macros.h>
-#include <brillo/errors/error.h>
 
 #include "update_engine/common/error_code.h"
 
diff --git a/common/error.h b/common/error.h
new file mode 100644
index 0000000..ab38e64
--- /dev/null
+++ b/common/error.h
@@ -0,0 +1,29 @@
+// Copyright (C) 2023 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+#pragma once
+
+#include "update_engine/common/error_code.h"
+#include <string>
+
+namespace chromeos_update_engine {
+
+struct Error {
+  ErrorCode error_code;
+  std::string message;
+  int line_number;
+  const char* file_name;
+};
+
+}  // namespace chromeos_update_engine