1 // Copyright 2018 The Dawn Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef DAWNNATIVE_ERROR_H_ 16 #define DAWNNATIVE_ERROR_H_ 17 18 #include "common/Result.h" 19 20 #include <string> 21 22 namespace dawn_native { 23 24 // This is the content of an error value for MaybeError or ResultOrError, split off to its own 25 // file to avoid having all files including headers like <string> and <vector> 26 class ErrorData; 27 28 enum class ErrorType : uint32_t { Validation, ContextLost, Unimplemented }; 29 30 // MaybeError and ResultOrError are meant to be used as return value for function that are not 31 // expected to, but might fail. The handling of error is potentially much slower than successes. 32 using MaybeError = Result<void, ErrorData*>; 33 34 template <typename T> 35 using ResultOrError = Result<T, ErrorData*>; 36 37 // Returning a success is done like so: 38 // return {}; // for Error 39 // return SomethingOfTypeT; // for ResultOrError<T> 40 // 41 // Returning an error is done via: 42 // return DAWN_MAKE_ERROR(errorType, "My error message"); 43 // 44 // but shorthand version for specific error types are preferred: 45 // return DAWN_VALIDATION_ERROR("My error message"); 46 #define DAWN_MAKE_ERROR(TYPE, MESSAGE) \ 47 ::dawn_native::MakeError(TYPE, MESSAGE, __FILE__, __func__, __LINE__) 48 #define DAWN_VALIDATION_ERROR(MESSAGE) DAWN_MAKE_ERROR(ErrorType::Validation, MESSAGE) 49 #define DAWN_CONTEXT_LOST_ERROR(MESSAGE) DAWN_MAKE_ERROR(ErrorType::ContextLost, MESSAGE) 50 #define DAWN_UNIMPLEMENTED_ERROR(MESSAGE) DAWN_MAKE_ERROR(ErrorType::Unimplemented, MESSAGE) 51 52 #define DAWN_CONCAT1(x, y) x##y 53 #define DAWN_CONCAT2(x, y) DAWN_CONCAT1(x, y) 54 #define DAWN_LOCAL_VAR DAWN_CONCAT2(_localVar, __LINE__) 55 56 // When Errors aren't handled explicitly, calls to functions returning errors should be 57 // wrapped in an DAWN_TRY. It will return the error if any, otherwise keep executing 58 // the current function. 59 #define DAWN_TRY(EXPR) \ 60 { \ 61 auto DAWN_LOCAL_VAR = EXPR; \ 62 if (DAWN_UNLIKELY(DAWN_LOCAL_VAR.IsError())) { \ 63 ErrorData* error = DAWN_LOCAL_VAR.AcquireError(); \ 64 ::dawn_native::AppendBacktrace(error, __FILE__, __func__, __LINE__); \ 65 return {std::move(error)}; \ 66 } \ 67 } \ 68 for (;;) \ 69 break 70 71 // DAWN_TRY_ASSIGN is the same as DAWN_TRY for ResultOrError and assigns the success value, if 72 // any, to VAR. 73 #define DAWN_TRY_ASSIGN(VAR, EXPR) \ 74 { \ 75 auto DAWN_LOCAL_VAR = EXPR; \ 76 if (DAWN_UNLIKELY(DAWN_LOCAL_VAR.IsError())) { \ 77 ErrorData* error = DAWN_LOCAL_VAR.AcquireError(); \ 78 ::dawn_native::AppendBacktrace(error, __FILE__, __func__, __LINE__); \ 79 return {std::move(error)}; \ 80 } \ 81 VAR = DAWN_LOCAL_VAR.AcquireSuccess(); \ 82 } \ 83 for (;;) \ 84 break 85 86 // Implementation detail of DAWN_TRY and DAWN_TRY_ASSIGN's adding to the Error's backtrace. 87 void AppendBacktrace(ErrorData* error, const char* file, const char* function, int line); 88 89 // Implementation detail of DAWN_MAKE_ERROR 90 ErrorData* MakeError(ErrorType type, 91 std::string message, 92 const char* file, 93 const char* function, 94 int line); 95 96 } // namespace dawn_native 97 98 #endif // DAWNNATIVE_ERROR_H_ 99