1*d9f75844SAndroid Build Coastguard Worker /* 2*d9f75844SAndroid Build Coastguard Worker * Copyright 2017 The WebRTC project authors. All Rights Reserved. 3*d9f75844SAndroid Build Coastguard Worker * 4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license 5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source 6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found 7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may 8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree. 9*d9f75844SAndroid Build Coastguard Worker */ 10*d9f75844SAndroid Build Coastguard Worker 11*d9f75844SAndroid Build Coastguard Worker #ifndef API_RTC_ERROR_H_ 12*d9f75844SAndroid Build Coastguard Worker #define API_RTC_ERROR_H_ 13*d9f75844SAndroid Build Coastguard Worker 14*d9f75844SAndroid Build Coastguard Worker #ifdef WEBRTC_UNIT_TEST 15*d9f75844SAndroid Build Coastguard Worker #include <ostream> 16*d9f75844SAndroid Build Coastguard Worker #endif // WEBRTC_UNIT_TEST 17*d9f75844SAndroid Build Coastguard Worker #include <string> 18*d9f75844SAndroid Build Coastguard Worker #include <utility> // For std::move. 19*d9f75844SAndroid Build Coastguard Worker 20*d9f75844SAndroid Build Coastguard Worker #include "absl/types/optional.h" 21*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/checks.h" 22*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/logging.h" 23*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/system/rtc_export.h" 24*d9f75844SAndroid Build Coastguard Worker 25*d9f75844SAndroid Build Coastguard Worker namespace webrtc { 26*d9f75844SAndroid Build Coastguard Worker 27*d9f75844SAndroid Build Coastguard Worker // Enumeration to represent distinct classes of errors that an application 28*d9f75844SAndroid Build Coastguard Worker // may wish to act upon differently. These roughly map to DOMExceptions or 29*d9f75844SAndroid Build Coastguard Worker // RTCError "errorDetailEnum" values in the web API, as described in the 30*d9f75844SAndroid Build Coastguard Worker // comments below. 31*d9f75844SAndroid Build Coastguard Worker enum class RTCErrorType { 32*d9f75844SAndroid Build Coastguard Worker // No error. 33*d9f75844SAndroid Build Coastguard Worker NONE, 34*d9f75844SAndroid Build Coastguard Worker 35*d9f75844SAndroid Build Coastguard Worker // An operation is valid, but currently unsupported. 36*d9f75844SAndroid Build Coastguard Worker // Maps to OperationError DOMException. 37*d9f75844SAndroid Build Coastguard Worker UNSUPPORTED_OPERATION, 38*d9f75844SAndroid Build Coastguard Worker 39*d9f75844SAndroid Build Coastguard Worker // A supplied parameter is valid, but currently unsupported. 40*d9f75844SAndroid Build Coastguard Worker // Maps to OperationError DOMException. 41*d9f75844SAndroid Build Coastguard Worker UNSUPPORTED_PARAMETER, 42*d9f75844SAndroid Build Coastguard Worker 43*d9f75844SAndroid Build Coastguard Worker // General error indicating that a supplied parameter is invalid. 44*d9f75844SAndroid Build Coastguard Worker // Maps to InvalidAccessError or TypeError DOMException depending on context. 45*d9f75844SAndroid Build Coastguard Worker INVALID_PARAMETER, 46*d9f75844SAndroid Build Coastguard Worker 47*d9f75844SAndroid Build Coastguard Worker // Slightly more specific than INVALID_PARAMETER; a parameter's value was 48*d9f75844SAndroid Build Coastguard Worker // outside the allowed range. 49*d9f75844SAndroid Build Coastguard Worker // Maps to RangeError DOMException. 50*d9f75844SAndroid Build Coastguard Worker INVALID_RANGE, 51*d9f75844SAndroid Build Coastguard Worker 52*d9f75844SAndroid Build Coastguard Worker // Slightly more specific than INVALID_PARAMETER; an error occurred while 53*d9f75844SAndroid Build Coastguard Worker // parsing string input. 54*d9f75844SAndroid Build Coastguard Worker // Maps to SyntaxError DOMException. 55*d9f75844SAndroid Build Coastguard Worker SYNTAX_ERROR, 56*d9f75844SAndroid Build Coastguard Worker 57*d9f75844SAndroid Build Coastguard Worker // The object does not support this operation in its current state. 58*d9f75844SAndroid Build Coastguard Worker // Maps to InvalidStateError DOMException. 59*d9f75844SAndroid Build Coastguard Worker INVALID_STATE, 60*d9f75844SAndroid Build Coastguard Worker 61*d9f75844SAndroid Build Coastguard Worker // An attempt was made to modify the object in an invalid way. 62*d9f75844SAndroid Build Coastguard Worker // Maps to InvalidModificationError DOMException. 63*d9f75844SAndroid Build Coastguard Worker INVALID_MODIFICATION, 64*d9f75844SAndroid Build Coastguard Worker 65*d9f75844SAndroid Build Coastguard Worker // An error occurred within an underlying network protocol. 66*d9f75844SAndroid Build Coastguard Worker // Maps to NetworkError DOMException. 67*d9f75844SAndroid Build Coastguard Worker NETWORK_ERROR, 68*d9f75844SAndroid Build Coastguard Worker 69*d9f75844SAndroid Build Coastguard Worker // Some resource has been exhausted; file handles, hardware resources, ports, 70*d9f75844SAndroid Build Coastguard Worker // etc. 71*d9f75844SAndroid Build Coastguard Worker // Maps to OperationError DOMException. 72*d9f75844SAndroid Build Coastguard Worker RESOURCE_EXHAUSTED, 73*d9f75844SAndroid Build Coastguard Worker 74*d9f75844SAndroid Build Coastguard Worker // The operation failed due to an internal error. 75*d9f75844SAndroid Build Coastguard Worker // Maps to OperationError DOMException. 76*d9f75844SAndroid Build Coastguard Worker INTERNAL_ERROR, 77*d9f75844SAndroid Build Coastguard Worker 78*d9f75844SAndroid Build Coastguard Worker // An error occured that has additional data. 79*d9f75844SAndroid Build Coastguard Worker // The additional data is specified in 80*d9f75844SAndroid Build Coastguard Worker // https://w3c.github.io/webrtc-pc/#rtcerror-interface 81*d9f75844SAndroid Build Coastguard Worker // Maps to RTCError DOMException. 82*d9f75844SAndroid Build Coastguard Worker OPERATION_ERROR_WITH_DATA, 83*d9f75844SAndroid Build Coastguard Worker }; 84*d9f75844SAndroid Build Coastguard Worker 85*d9f75844SAndroid Build Coastguard Worker // Detail information, showing what further information should be present. 86*d9f75844SAndroid Build Coastguard Worker // https://w3c.github.io/webrtc-pc/#rtcerrordetailtype-enum 87*d9f75844SAndroid Build Coastguard Worker enum class RTCErrorDetailType { 88*d9f75844SAndroid Build Coastguard Worker NONE, 89*d9f75844SAndroid Build Coastguard Worker DATA_CHANNEL_FAILURE, 90*d9f75844SAndroid Build Coastguard Worker DTLS_FAILURE, 91*d9f75844SAndroid Build Coastguard Worker FINGERPRINT_FAILURE, 92*d9f75844SAndroid Build Coastguard Worker SCTP_FAILURE, 93*d9f75844SAndroid Build Coastguard Worker SDP_SYNTAX_ERROR, 94*d9f75844SAndroid Build Coastguard Worker HARDWARE_ENCODER_NOT_AVAILABLE, 95*d9f75844SAndroid Build Coastguard Worker HARDWARE_ENCODER_ERROR, 96*d9f75844SAndroid Build Coastguard Worker }; 97*d9f75844SAndroid Build Coastguard Worker 98*d9f75844SAndroid Build Coastguard Worker // Roughly corresponds to RTCError in the web api. Holds an error type, a 99*d9f75844SAndroid Build Coastguard Worker // message, and possibly additional information specific to that error. 100*d9f75844SAndroid Build Coastguard Worker // 101*d9f75844SAndroid Build Coastguard Worker // Doesn't contain anything beyond a type and message now, but will in the 102*d9f75844SAndroid Build Coastguard Worker // future as more errors are implemented. 103*d9f75844SAndroid Build Coastguard Worker class RTC_EXPORT RTCError { 104*d9f75844SAndroid Build Coastguard Worker public: 105*d9f75844SAndroid Build Coastguard Worker // Constructors. 106*d9f75844SAndroid Build Coastguard Worker 107*d9f75844SAndroid Build Coastguard Worker // Creates a "no error" error. RTCError()108*d9f75844SAndroid Build Coastguard Worker RTCError() {} RTCError(RTCErrorType type)109*d9f75844SAndroid Build Coastguard Worker explicit RTCError(RTCErrorType type) : type_(type) {} 110*d9f75844SAndroid Build Coastguard Worker RTCError(RTCErrorType type,std::string message)111*d9f75844SAndroid Build Coastguard Worker RTCError(RTCErrorType type, std::string message) 112*d9f75844SAndroid Build Coastguard Worker : type_(type), message_(std::move(message)) {} 113*d9f75844SAndroid Build Coastguard Worker 114*d9f75844SAndroid Build Coastguard Worker // In many use cases, it is better to use move than copy, 115*d9f75844SAndroid Build Coastguard Worker // but copy and assignment are provided for those cases that need it. 116*d9f75844SAndroid Build Coastguard Worker // Note that this has extra overhead because it copies strings. 117*d9f75844SAndroid Build Coastguard Worker RTCError(const RTCError& other) = default; 118*d9f75844SAndroid Build Coastguard Worker RTCError(RTCError&&) = default; 119*d9f75844SAndroid Build Coastguard Worker RTCError& operator=(const RTCError& other) = default; 120*d9f75844SAndroid Build Coastguard Worker RTCError& operator=(RTCError&&) = default; 121*d9f75844SAndroid Build Coastguard Worker 122*d9f75844SAndroid Build Coastguard Worker // Identical to default constructed error. 123*d9f75844SAndroid Build Coastguard Worker // 124*d9f75844SAndroid Build Coastguard Worker // Preferred over the default constructor for code readability. 125*d9f75844SAndroid Build Coastguard Worker static RTCError OK(); 126*d9f75844SAndroid Build Coastguard Worker 127*d9f75844SAndroid Build Coastguard Worker // Error type. type()128*d9f75844SAndroid Build Coastguard Worker RTCErrorType type() const { return type_; } set_type(RTCErrorType type)129*d9f75844SAndroid Build Coastguard Worker void set_type(RTCErrorType type) { type_ = type; } 130*d9f75844SAndroid Build Coastguard Worker 131*d9f75844SAndroid Build Coastguard Worker // Human-readable message describing the error. Shouldn't be used for 132*d9f75844SAndroid Build Coastguard Worker // anything but logging/diagnostics, since messages are not guaranteed to be 133*d9f75844SAndroid Build Coastguard Worker // stable. 134*d9f75844SAndroid Build Coastguard Worker const char* message() const; 135*d9f75844SAndroid Build Coastguard Worker 136*d9f75844SAndroid Build Coastguard Worker void set_message(std::string message); 137*d9f75844SAndroid Build Coastguard Worker error_detail()138*d9f75844SAndroid Build Coastguard Worker RTCErrorDetailType error_detail() const { return error_detail_; } set_error_detail(RTCErrorDetailType detail)139*d9f75844SAndroid Build Coastguard Worker void set_error_detail(RTCErrorDetailType detail) { error_detail_ = detail; } sctp_cause_code()140*d9f75844SAndroid Build Coastguard Worker absl::optional<uint16_t> sctp_cause_code() const { return sctp_cause_code_; } set_sctp_cause_code(uint16_t cause_code)141*d9f75844SAndroid Build Coastguard Worker void set_sctp_cause_code(uint16_t cause_code) { 142*d9f75844SAndroid Build Coastguard Worker sctp_cause_code_ = cause_code; 143*d9f75844SAndroid Build Coastguard Worker } 144*d9f75844SAndroid Build Coastguard Worker 145*d9f75844SAndroid Build Coastguard Worker // Convenience method for situations where you only care whether or not an 146*d9f75844SAndroid Build Coastguard Worker // error occurred. ok()147*d9f75844SAndroid Build Coastguard Worker bool ok() const { return type_ == RTCErrorType::NONE; } 148*d9f75844SAndroid Build Coastguard Worker 149*d9f75844SAndroid Build Coastguard Worker private: 150*d9f75844SAndroid Build Coastguard Worker RTCErrorType type_ = RTCErrorType::NONE; 151*d9f75844SAndroid Build Coastguard Worker std::string message_; 152*d9f75844SAndroid Build Coastguard Worker RTCErrorDetailType error_detail_ = RTCErrorDetailType::NONE; 153*d9f75844SAndroid Build Coastguard Worker absl::optional<uint16_t> sctp_cause_code_; 154*d9f75844SAndroid Build Coastguard Worker }; 155*d9f75844SAndroid Build Coastguard Worker 156*d9f75844SAndroid Build Coastguard Worker // Outputs the error as a friendly string. Update this method when adding a new 157*d9f75844SAndroid Build Coastguard Worker // error type. 158*d9f75844SAndroid Build Coastguard Worker // 159*d9f75844SAndroid Build Coastguard Worker // Only intended to be used for logging/diagnostics. The returned char* points 160*d9f75844SAndroid Build Coastguard Worker // to literal string that lives for the whole duration of the program. 161*d9f75844SAndroid Build Coastguard Worker RTC_EXPORT const char* ToString(RTCErrorType error); 162*d9f75844SAndroid Build Coastguard Worker RTC_EXPORT const char* ToString(RTCErrorDetailType error); 163*d9f75844SAndroid Build Coastguard Worker 164*d9f75844SAndroid Build Coastguard Worker #ifdef WEBRTC_UNIT_TEST 165*d9f75844SAndroid Build Coastguard Worker inline std::ostream& operator<<( // no-presubmit-check TODO(webrtc:8982) 166*d9f75844SAndroid Build Coastguard Worker std::ostream& stream, // no-presubmit-check TODO(webrtc:8982) 167*d9f75844SAndroid Build Coastguard Worker RTCErrorType error) { 168*d9f75844SAndroid Build Coastguard Worker return stream << ToString(error); 169*d9f75844SAndroid Build Coastguard Worker } 170*d9f75844SAndroid Build Coastguard Worker 171*d9f75844SAndroid Build Coastguard Worker inline std::ostream& operator<<( // no-presubmit-check TODO(webrtc:8982) 172*d9f75844SAndroid Build Coastguard Worker std::ostream& stream, // no-presubmit-check TODO(webrtc:8982) 173*d9f75844SAndroid Build Coastguard Worker RTCErrorDetailType error) { 174*d9f75844SAndroid Build Coastguard Worker return stream << ToString(error); 175*d9f75844SAndroid Build Coastguard Worker } 176*d9f75844SAndroid Build Coastguard Worker #endif // WEBRTC_UNIT_TEST 177*d9f75844SAndroid Build Coastguard Worker 178*d9f75844SAndroid Build Coastguard Worker // Helper macro that can be used by implementations to create an error with a 179*d9f75844SAndroid Build Coastguard Worker // message and log it. `message` should be a string literal or movable 180*d9f75844SAndroid Build Coastguard Worker // std::string. 181*d9f75844SAndroid Build Coastguard Worker #define LOG_AND_RETURN_ERROR_EX(type, message, severity) \ 182*d9f75844SAndroid Build Coastguard Worker { \ 183*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(type != RTCErrorType::NONE); \ 184*d9f75844SAndroid Build Coastguard Worker RTC_LOG(severity) << message << " (" << ::webrtc::ToString(type) << ")"; \ 185*d9f75844SAndroid Build Coastguard Worker return ::webrtc::RTCError(type, message); \ 186*d9f75844SAndroid Build Coastguard Worker } 187*d9f75844SAndroid Build Coastguard Worker 188*d9f75844SAndroid Build Coastguard Worker #define LOG_AND_RETURN_ERROR(type, message) \ 189*d9f75844SAndroid Build Coastguard Worker LOG_AND_RETURN_ERROR_EX(type, message, LS_ERROR) 190*d9f75844SAndroid Build Coastguard Worker 191*d9f75844SAndroid Build Coastguard Worker // RTCErrorOr<T> is the union of an RTCError object and a T object. RTCErrorOr 192*d9f75844SAndroid Build Coastguard Worker // models the concept of an object that is either a usable value, or an error 193*d9f75844SAndroid Build Coastguard Worker // Status explaining why such a value is not present. To this end RTCErrorOr<T> 194*d9f75844SAndroid Build Coastguard Worker // does not allow its RTCErrorType value to be RTCErrorType::NONE. This is 195*d9f75844SAndroid Build Coastguard Worker // enforced by a debug check in most cases. 196*d9f75844SAndroid Build Coastguard Worker // 197*d9f75844SAndroid Build Coastguard Worker // The primary use-case for RTCErrorOr<T> is as the return value of a function 198*d9f75844SAndroid Build Coastguard Worker // which may fail. For example, CreateRtpSender will fail if the parameters 199*d9f75844SAndroid Build Coastguard Worker // could not be successfully applied at the media engine level, but if 200*d9f75844SAndroid Build Coastguard Worker // successful will return a unique_ptr to an RtpSender. 201*d9f75844SAndroid Build Coastguard Worker // 202*d9f75844SAndroid Build Coastguard Worker // Example client usage for a RTCErrorOr<std::unique_ptr<T>>: 203*d9f75844SAndroid Build Coastguard Worker // 204*d9f75844SAndroid Build Coastguard Worker // RTCErrorOr<std::unique_ptr<Foo>> result = FooFactory::MakeNewFoo(arg); 205*d9f75844SAndroid Build Coastguard Worker // if (result.ok()) { 206*d9f75844SAndroid Build Coastguard Worker // std::unique_ptr<Foo> foo = result.ConsumeValue(); 207*d9f75844SAndroid Build Coastguard Worker // foo->DoSomethingCool(); 208*d9f75844SAndroid Build Coastguard Worker // } else { 209*d9f75844SAndroid Build Coastguard Worker // RTC_LOG(LS_ERROR) << result.error(); 210*d9f75844SAndroid Build Coastguard Worker // } 211*d9f75844SAndroid Build Coastguard Worker // 212*d9f75844SAndroid Build Coastguard Worker // Example factory implementation returning RTCErrorOr<std::unique_ptr<T>>: 213*d9f75844SAndroid Build Coastguard Worker // 214*d9f75844SAndroid Build Coastguard Worker // RTCErrorOr<std::unique_ptr<Foo>> FooFactory::MakeNewFoo(int arg) { 215*d9f75844SAndroid Build Coastguard Worker // if (arg <= 0) { 216*d9f75844SAndroid Build Coastguard Worker // return RTCError(RTCErrorType::INVALID_RANGE, "Arg must be positive"); 217*d9f75844SAndroid Build Coastguard Worker // } else { 218*d9f75844SAndroid Build Coastguard Worker // return std::unique_ptr<Foo>(new Foo(arg)); 219*d9f75844SAndroid Build Coastguard Worker // } 220*d9f75844SAndroid Build Coastguard Worker // } 221*d9f75844SAndroid Build Coastguard Worker // 222*d9f75844SAndroid Build Coastguard Worker template <typename T> 223*d9f75844SAndroid Build Coastguard Worker class RTCErrorOr { 224*d9f75844SAndroid Build Coastguard Worker // Used to convert between RTCErrorOr<Foo>/RtcErrorOr<Bar>, when an implicit 225*d9f75844SAndroid Build Coastguard Worker // conversion from Foo to Bar exists. 226*d9f75844SAndroid Build Coastguard Worker template <typename U> 227*d9f75844SAndroid Build Coastguard Worker friend class RTCErrorOr; 228*d9f75844SAndroid Build Coastguard Worker 229*d9f75844SAndroid Build Coastguard Worker public: 230*d9f75844SAndroid Build Coastguard Worker typedef T element_type; 231*d9f75844SAndroid Build Coastguard Worker 232*d9f75844SAndroid Build Coastguard Worker // Constructs a new RTCErrorOr with RTCErrorType::INTERNAL_ERROR error. This 233*d9f75844SAndroid Build Coastguard Worker // is marked 'explicit' to try to catch cases like 'return {};', where people 234*d9f75844SAndroid Build Coastguard Worker // think RTCErrorOr<std::vector<int>> will be initialized with an empty 235*d9f75844SAndroid Build Coastguard Worker // vector, instead of a RTCErrorType::INTERNAL_ERROR error. RTCErrorOr()236*d9f75844SAndroid Build Coastguard Worker RTCErrorOr() : error_(RTCErrorType::INTERNAL_ERROR) {} 237*d9f75844SAndroid Build Coastguard Worker 238*d9f75844SAndroid Build Coastguard Worker // Constructs a new RTCErrorOr with the given non-ok error. After calling 239*d9f75844SAndroid Build Coastguard Worker // this constructor, calls to value() will DCHECK-fail. 240*d9f75844SAndroid Build Coastguard Worker // 241*d9f75844SAndroid Build Coastguard Worker // NOTE: Not explicit - we want to use RTCErrorOr<T> as a return 242*d9f75844SAndroid Build Coastguard Worker // value, so it is convenient and sensible to be able to do 'return 243*d9f75844SAndroid Build Coastguard Worker // RTCError(...)' when the return type is RTCErrorOr<T>. 244*d9f75844SAndroid Build Coastguard Worker // 245*d9f75844SAndroid Build Coastguard Worker // REQUIRES: !error.ok(). This requirement is DCHECKed. RTCErrorOr(RTCError && error)246*d9f75844SAndroid Build Coastguard Worker RTCErrorOr(RTCError&& error) : error_(std::move(error)) { // NOLINT 247*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(!error_.ok()); 248*d9f75844SAndroid Build Coastguard Worker } 249*d9f75844SAndroid Build Coastguard Worker 250*d9f75844SAndroid Build Coastguard Worker // Constructs a new RTCErrorOr with the given value. After calling this 251*d9f75844SAndroid Build Coastguard Worker // constructor, calls to value() will succeed, and calls to error() will 252*d9f75844SAndroid Build Coastguard Worker // return a default-constructed RTCError. 253*d9f75844SAndroid Build Coastguard Worker // 254*d9f75844SAndroid Build Coastguard Worker // NOTE: Not explicit - we want to use RTCErrorOr<T> as a return type 255*d9f75844SAndroid Build Coastguard Worker // so it is convenient and sensible to be able to do 'return T()' 256*d9f75844SAndroid Build Coastguard Worker // when the return type is RTCErrorOr<T>. RTCErrorOr(const T & value)257*d9f75844SAndroid Build Coastguard Worker RTCErrorOr(const T& value) : value_(value) {} // NOLINT RTCErrorOr(T && value)258*d9f75844SAndroid Build Coastguard Worker RTCErrorOr(T&& value) : value_(std::move(value)) {} // NOLINT 259*d9f75844SAndroid Build Coastguard Worker 260*d9f75844SAndroid Build Coastguard Worker // Delete the copy constructor and assignment operator; there aren't any use 261*d9f75844SAndroid Build Coastguard Worker // cases where you should need to copy an RTCErrorOr, as opposed to moving 262*d9f75844SAndroid Build Coastguard Worker // it. Can revisit this decision if use cases arise in the future. 263*d9f75844SAndroid Build Coastguard Worker RTCErrorOr(const RTCErrorOr& other) = delete; 264*d9f75844SAndroid Build Coastguard Worker RTCErrorOr& operator=(const RTCErrorOr& other) = delete; 265*d9f75844SAndroid Build Coastguard Worker 266*d9f75844SAndroid Build Coastguard Worker // Move constructor and move-assignment operator. 267*d9f75844SAndroid Build Coastguard Worker // 268*d9f75844SAndroid Build Coastguard Worker // Visual Studio doesn't support "= default" with move constructors or 269*d9f75844SAndroid Build Coastguard Worker // assignment operators (even though they compile, they segfault), so define 270*d9f75844SAndroid Build Coastguard Worker // them explicitly. RTCErrorOr(RTCErrorOr && other)271*d9f75844SAndroid Build Coastguard Worker RTCErrorOr(RTCErrorOr&& other) 272*d9f75844SAndroid Build Coastguard Worker : error_(std::move(other.error_)), value_(std::move(other.value_)) {} 273*d9f75844SAndroid Build Coastguard Worker RTCErrorOr& operator=(RTCErrorOr&& other) { 274*d9f75844SAndroid Build Coastguard Worker error_ = std::move(other.error_); 275*d9f75844SAndroid Build Coastguard Worker value_ = std::move(other.value_); 276*d9f75844SAndroid Build Coastguard Worker return *this; 277*d9f75844SAndroid Build Coastguard Worker } 278*d9f75844SAndroid Build Coastguard Worker 279*d9f75844SAndroid Build Coastguard Worker // Conversion constructor and assignment operator; T must be copy or move 280*d9f75844SAndroid Build Coastguard Worker // constructible from U. 281*d9f75844SAndroid Build Coastguard Worker template <typename U> RTCErrorOr(RTCErrorOr<U> other)282*d9f75844SAndroid Build Coastguard Worker RTCErrorOr(RTCErrorOr<U> other) // NOLINT 283*d9f75844SAndroid Build Coastguard Worker : error_(std::move(other.error_)), value_(std::move(other.value_)) {} 284*d9f75844SAndroid Build Coastguard Worker template <typename U> 285*d9f75844SAndroid Build Coastguard Worker RTCErrorOr& operator=(RTCErrorOr<U> other) { 286*d9f75844SAndroid Build Coastguard Worker error_ = std::move(other.error_); 287*d9f75844SAndroid Build Coastguard Worker value_ = std::move(other.value_); 288*d9f75844SAndroid Build Coastguard Worker return *this; 289*d9f75844SAndroid Build Coastguard Worker } 290*d9f75844SAndroid Build Coastguard Worker 291*d9f75844SAndroid Build Coastguard Worker // Returns a reference to our error. If this contains a T, then returns 292*d9f75844SAndroid Build Coastguard Worker // default-constructed RTCError. error()293*d9f75844SAndroid Build Coastguard Worker const RTCError& error() const { return error_; } 294*d9f75844SAndroid Build Coastguard Worker 295*d9f75844SAndroid Build Coastguard Worker // Moves the error. Can be useful if, say "CreateFoo" returns an 296*d9f75844SAndroid Build Coastguard Worker // RTCErrorOr<Foo>, and internally calls "CreateBar" which returns an 297*d9f75844SAndroid Build Coastguard Worker // RTCErrorOr<Bar>, and wants to forward the error up the stack. MoveError()298*d9f75844SAndroid Build Coastguard Worker RTCError MoveError() { return std::move(error_); } 299*d9f75844SAndroid Build Coastguard Worker 300*d9f75844SAndroid Build Coastguard Worker // Returns this->error().ok() ok()301*d9f75844SAndroid Build Coastguard Worker bool ok() const { return error_.ok(); } 302*d9f75844SAndroid Build Coastguard Worker 303*d9f75844SAndroid Build Coastguard Worker // Returns a reference to our current value, or DCHECK-fails if !this->ok(). 304*d9f75844SAndroid Build Coastguard Worker // 305*d9f75844SAndroid Build Coastguard Worker // Can be convenient for the implementation; for example, a method may want 306*d9f75844SAndroid Build Coastguard Worker // to access the value in some way before returning it to the next method on 307*d9f75844SAndroid Build Coastguard Worker // the stack. value()308*d9f75844SAndroid Build Coastguard Worker const T& value() const { 309*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(ok()); 310*d9f75844SAndroid Build Coastguard Worker return value_; 311*d9f75844SAndroid Build Coastguard Worker } value()312*d9f75844SAndroid Build Coastguard Worker T& value() { 313*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(ok()); 314*d9f75844SAndroid Build Coastguard Worker return value_; 315*d9f75844SAndroid Build Coastguard Worker } 316*d9f75844SAndroid Build Coastguard Worker 317*d9f75844SAndroid Build Coastguard Worker // Moves our current value out of this object and returns it, or DCHECK-fails 318*d9f75844SAndroid Build Coastguard Worker // if !this->ok(). MoveValue()319*d9f75844SAndroid Build Coastguard Worker T MoveValue() { 320*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(ok()); 321*d9f75844SAndroid Build Coastguard Worker return std::move(value_); 322*d9f75844SAndroid Build Coastguard Worker } 323*d9f75844SAndroid Build Coastguard Worker 324*d9f75844SAndroid Build Coastguard Worker private: 325*d9f75844SAndroid Build Coastguard Worker RTCError error_; 326*d9f75844SAndroid Build Coastguard Worker T value_; 327*d9f75844SAndroid Build Coastguard Worker }; 328*d9f75844SAndroid Build Coastguard Worker 329*d9f75844SAndroid Build Coastguard Worker } // namespace webrtc 330*d9f75844SAndroid Build Coastguard Worker 331*d9f75844SAndroid Build Coastguard Worker #endif // API_RTC_ERROR_H_ 332