Home | History | Annotate | Download | only in weave
      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