1 /**
2 * \file wasmtime/error.hh
3 */
4
5 #ifndef WASMTIME_ERROR_HH
6 #define WASMTIME_ERROR_HH
7
8 #include <memory>
9 #include <optional>
10 #include <ostream>
11 #include <string>
12 #include <variant>
13 #include <wasmtime/error.h>
14 #include <wasmtime/helpers.hh>
15
16 namespace wasmtime {
17
18 class Trace;
19
20 /**
21 * \brief Errors coming from Wasmtime
22 *
23 * This class represents an error that came from Wasmtime and contains a textual
24 * description of the error that occurred.
25 */
26 class Error {
27 WASMTIME_OWN_WRAPPER(Error, wasmtime_error);
28
29 /// \brief Creates an error with the provided message.
Error(const std::string & s)30 Error(const std::string &s) : ptr(wasmtime_error_new(s.c_str())) {}
31
32 /// \brief Returns the error message associated with this error.
message() const33 std::string message() const {
34 wasm_byte_vec_t msg_bytes;
35 wasmtime_error_message(ptr.get(), &msg_bytes);
36 auto ret = std::string(msg_bytes.data, msg_bytes.size);
37 wasm_byte_vec_delete(&msg_bytes);
38 return ret;
39 }
40
41 /// If this trap represents a call to `exit` for WASI, this will return the
42 /// optional error code associated with the exit trap.
i32_exit() const43 std::optional<int32_t> i32_exit() const {
44 int32_t status = 0;
45 if (wasmtime_error_exit_status(ptr.get(), &status)) {
46 return status;
47 }
48 return std::nullopt;
49 }
50
51 /// Returns the trace of WebAssembly frames associated with this error.
52 ///
53 /// Note that the `trace` cannot outlive this error object.
54 Trace trace() const;
55 };
56
57 /// \brief Used to print an error.
operator <<(std::ostream & os,const Error & e)58 inline std::ostream &operator<<(std::ostream &os, const Error &e) {
59 os << e.message();
60 return os;
61 }
62
63 /**
64 * \brief Fallible result type used for Wasmtime.
65 *
66 * This type is used as the return value of many methods in the Wasmtime API.
67 * This behaves similarly to Rust's `Result<T, E>` and will be replaced with a
68 * C++ standard when it exists.
69 */
70 template <typename T, typename E = Error> class [[nodiscard]] Result {
71 std::variant<T, E> data;
72
73 public:
74 /// \brief Creates a `Result` from its successful value.
Result(T t)75 Result(T t) : data(std::move(t)) {}
76 /// \brief Creates a `Result` from an error value.
Result(E e)77 Result(E e) : data(std::move(e)) {}
78
79 /// \brief Returns `true` if this result is a success, `false` if it's an
80 /// error
operator bool() const81 explicit operator bool() const { return data.index() == 0; }
82
83 /// \brief Returns the error, if present, aborts if this is not an error.
err()84 E &&err() { return std::get<E>(std::move(data)); }
85 /// \brief Returns the error, if present, aborts if this is not an error.
err() const86 const E &&err() const { return std::get<E>(std::move(data)); }
87
88 /// \brief Returns the success, if present, aborts if this is an error.
ok()89 T &&ok() { return std::get<T>(std::move(data)); }
90 /// \brief Returns the success, if present, aborts if this is an error.
ok() const91 const T &&ok() const { return std::get<T>(std::move(data)); }
92
93 /// \brief Returns the success, if present, aborts if this is an error.
ok_ref()94 T &ok_ref() { return std::get<T>(data); }
95 /// \brief Returns the success, if present, aborts if this is an error.
ok_ref() const96 const T &ok_ref() const { return std::get<T>(data); }
97
98 /// \brief Returns the error, if present, aborts if this is not an error.
err_ref()99 E &err_ref() { return std::get<T>(data); }
100 /// \brief Returns the error, if present, aborts if this is not an error.
err_ref() const101 const E &err_ref() const { return std::get<T>(data); }
102
103 /// \brief Returns the success, if present, aborts if this is an error.
unwrap()104 T unwrap() {
105 if (*this) {
106 return this->ok();
107 }
108 unwrap_failed();
109 }
110
111 private:
unwrap_failed()112 [[noreturn]] void unwrap_failed() {
113 fprintf(stderr, "error: %s\n", this->err().message().c_str()); // NOLINT
114 std::abort();
115 }
116 };
117
118 } // namespace wasmtime
119
120 #endif // WASMTIME_ERROR_HH
121