1 // Copyright 2015 The Weave 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 LIBWEAVE_INCLUDE_WEAVE_ERROR_H_ 6 #define LIBWEAVE_INCLUDE_WEAVE_ERROR_H_ 7 8 #include <memory> 9 #include <string> 10 11 #include <base/callback.h> 12 #include <base/compiler_specific.h> 13 #include <base/location.h> 14 #include <base/macros.h> 15 #include <weave/export.h> 16 17 namespace weave { 18 19 class Error; // Forward declaration. 20 21 using ErrorPtr = std::unique_ptr<Error>; 22 23 class LIBWEAVE_EXPORT Error final { 24 public: 25 ~Error() = default; 26 27 class AddToTypeProxy { 28 public: 29 operator bool() const { return false; } 30 31 template <class T> 32 operator std::unique_ptr<T>() const { 33 return nullptr; 34 } 35 36 template <class T> 37 operator T*() const { 38 return nullptr; 39 } 40 }; 41 42 // Creates an instance of Error class. 43 static ErrorPtr Create(const tracked_objects::Location& location, 44 const std::string& code, 45 const std::string& message); 46 static ErrorPtr Create(const tracked_objects::Location& location, 47 const std::string& code, 48 const std::string& message, 49 ErrorPtr inner_error); 50 // If |error| is not nullptr, creates another instance of Error class, 51 // initializes it with specified arguments and adds it to the head of 52 // the error chain pointed to by |error|. 53 static AddToTypeProxy AddTo(ErrorPtr* error, 54 const tracked_objects::Location& location, 55 const std::string& code, 56 const std::string& message); 57 // Same as the Error::AddTo above, but allows to pass in a printf-like 58 // format string and optional parameters to format the error message. 59 static AddToTypeProxy AddToPrintf(ErrorPtr* error, 60 const tracked_objects::Location& location, 61 const std::string& code, 62 const char* format, 63 ...) PRINTF_FORMAT(4, 5); 64 65 // Clones error with all inner errors. 66 ErrorPtr Clone() const; 67 68 // Returns the error code and message 69 const std::string& GetCode() const { return code_; } 70 const std::string& GetMessage() const { return message_; } 71 72 // Returns the location of the error in the source code. 73 const tracked_objects::LocationSnapshot& GetLocation() const { 74 return location_; 75 } 76 77 // Checks if this or any of the inner errors in the chain matches the 78 // specified error code. 79 bool HasError(const std::string& code) const; 80 81 // Gets a pointer to the inner error, if present. Returns nullptr otherwise. 82 const Error* GetInnerError() const { return inner_error_.get(); } 83 84 // Gets a pointer to the first error occurred. 85 // Returns itself if no inner error are available. 86 const Error* GetFirstError() const; 87 88 // Finds an error with the given code in the error chain stating at 89 // |error_chain_start|. Returns the pointer to the first matching error 90 // 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& code); 94 95 protected: 96 // Constructor is protected since this object is supposed to be 97 // created via the Create factory methods. 98 Error(const tracked_objects::Location& location, 99 const std::string& code, 100 const std::string& message, 101 ErrorPtr inner_error); 102 103 Error(const tracked_objects::LocationSnapshot& location, 104 const std::string& code, 105 const std::string& message, 106 ErrorPtr inner_error); 107 108 // Error code. A unique error code identifier. 109 std::string code_; 110 // Human-readable error message. 111 std::string message_; 112 // Error origin in the source code. 113 tracked_objects::LocationSnapshot location_; 114 // Pointer to inner error, if any. This forms a chain of errors. 115 ErrorPtr inner_error_; 116 117 private: 118 DISALLOW_COPY_AND_ASSIGN(Error); 119 }; 120 121 // Default callback type for async operations. 122 // Function having this callback as argument should call the callback exactly 123 // one time. 124 // Successfully completed operation should run callback with |error| set to 125 // null. Failed operation should run callback with |error| containing error 126 // details. 127 using DoneCallback = base::Callback<void(ErrorPtr error)>; 128 129 } // namespace weave 130 131 #endif // LIBWEAVE_INCLUDE_WEAVE_ERROR_H_ 132