1 // Copyright 2014 The Chromium OS Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef LIBBRILLO_BRILLO_ERRORS_ERROR_H_ 6 #define LIBBRILLO_BRILLO_ERRORS_ERROR_H_ 7 8 #include <memory> 9 #include <string> 10 11 #include <base/location.h> 12 #include <base/macros.h> 13 #include <brillo/brillo_export.h> 14 15 namespace brillo { 16 17 class Error; // Forward declaration. 18 19 using ErrorPtr = std::unique_ptr<Error>; 20 21 class BRILLO_EXPORT Error { 22 public: 23 virtual ~Error() = default; 24 25 // Creates an instance of Error class. 26 static ErrorPtr Create(const base::Location& location, 27 const std::string& domain, 28 const std::string& code, 29 const std::string& message); 30 static ErrorPtr Create(const base::Location& location, 31 const std::string& domain, 32 const std::string& code, 33 const std::string& message, 34 ErrorPtr inner_error); 35 // If |error| is not nullptr, creates another instance of Error class, 36 // initializes it with specified arguments and adds it to the head of 37 // the error chain pointed to by |error|. 38 static void AddTo(ErrorPtr* error, 39 const base::Location& location, 40 const std::string& domain, 41 const std::string& code, 42 const std::string& message); 43 // Same as the Error::AddTo above, but allows to pass in a printf-like 44 // format string and optional parameters to format the error message. 45 static void AddToPrintf(ErrorPtr* error, 46 const base::Location& location, 47 const std::string& domain, 48 const std::string& code, 49 const char* format, 50 ...) PRINTF_FORMAT(5, 6); 51 52 // Clones error with all inner errors. 53 ErrorPtr Clone() const; 54 55 // Returns the error domain, code and message GetDomain()56 const std::string& GetDomain() const { return domain_; } GetCode()57 const std::string& GetCode() const { return code_; } GetMessage()58 const std::string& GetMessage() const { return message_; } 59 60 // Returns the location of the error in the source code. GetLocation()61 const base::Location& GetLocation() const { 62 return location_; 63 } 64 65 // Checks if this or any of the inner errors in the chain has the specified 66 // error domain. 67 bool HasDomain(const std::string& domain) const; 68 69 // Checks if this or any of the inner errors in the chain matches the 70 // specified error domain and code. 71 bool HasError(const std::string& domain, const std::string& code) const; 72 73 // Gets a pointer to the inner error, if present. Returns nullptr otherwise. GetInnerError()74 const Error* GetInnerError() const { return inner_error_.get(); } 75 76 // Gets a pointer to the first error occurred. 77 // Returns itself if no inner error are available. 78 const Error* GetFirstError() const; 79 80 // Finds an error object of particular domain in the error chain stating at 81 // |error_chain_start|. Returns the a pointer to the first matching error 82 // object found. 83 // Returns nullptr if no match is found. 84 // This method is safe to call on a nullptr |error_chain_start| in which case 85 // the result will also be nullptr. 86 static const Error* FindErrorOfDomain(const Error* error_chain_start, 87 const std::string& domain); 88 // Finds an error of particular domain with the given code in the error chain 89 // stating at |error_chain_start|. Returns the pointer to the first matching 90 // error object. 91 // Returns nullptr if no match is found or if |error_chain_start| is nullptr. 92 static const Error* FindError(const Error* error_chain_start, 93 const std::string& domain, 94 const std::string& code); 95 96 protected: 97 // Constructor is protected since this object is supposed to be 98 // created via the Create factory methods. 99 Error(const base::Location& location, 100 const std::string& domain, 101 const std::string& code, 102 const std::string& message, 103 ErrorPtr inner_error); 104 105 // Error domain. The domain defines the scopes for error codes. 106 // Two errors with the same code but different domains are different errors. 107 std::string domain_; 108 // Error code. A unique error code identifier within the given domain. 109 std::string code_; 110 // Human-readable error message. 111 std::string message_; 112 // Error origin in the source code. 113 // TODO(crbug.com/980935): Consider dropping this. 114 base::Location location_; 115 // Pointer to inner error, if any. This forms a chain of errors. 116 ErrorPtr inner_error_; 117 118 private: 119 DISALLOW_COPY_AND_ASSIGN(Error); 120 }; 121 122 } // namespace brillo 123 124 #endif // LIBBRILLO_BRILLO_ERRORS_ERROR_H_ 125