-
Notifications
You must be signed in to change notification settings - Fork 82
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Consider adding an error
type
#389
Comments
All in all: this seems sensible to me. The concept of "errors" are definitely ubiquitous enough to warrant special casing in the component model.
If you were to translate this to today's WIT syntax, does this mean that
Makes sense. Does the payload field behavior need to be special-cased for |
I'm not proposing to change the meaning of
I think error payloads can only include pure (stateless, identity-less) values, which rules out handles, futures, streams and buffers and thus it wouldn't be a true " |
Okay👍. Out of curiosity: why's that? |
If |
I think it would be beneficial to add a built-in
error
type to the Component Model and WIT to serve as the go-to type to use when you want to propagate rich error information for the benefit of debugging. With this type,result<T, error>
would become the common return type of fallible functions.Just as a high-level sketch to paint a picture:
error
could have (immutable) value semantics but be represented in core wasm as ani32
index into an error table managed by the runtime (like resources/handles), allowing it to be efficiently propagated between components without the usual linear-memory copy of normal values.error
values could contain a boxed heterogeneous value payload that is supplied by wasm when creating anerror
(via some newerror.new
canon built-in) and can be conditionally extracted by wasm (via some other newcanon.payload
built-in) if the payload type dynamically matches.error
values could also contain context information (incl. a callstack) that would be automatically filled in by the host atcanon.new
and could be repeatedly extended (by creating newerror
values from the oldererror
values) with additional context when propagating anerror
.error
values could be logged directly (via theiri32
index passed to another new canon built-in) such that the host could easily do a nice job rendering the context for the developer (analogous to how browser consoles nicely render the stacks of uncaughtError
objects)Some potential benefits of having
error
be built-in include:error
to the languages' idiomatic error-with-context constructs (e.g., a JSError
object or Rustanyhow::Error
)error
is created" runtime option to help debug cases where errors are swallowed or handled incorrectly (similar to first-chance exceptions).error
and all associated payload-accessor functions (likehttp-error-code
) could be removed. These are currently a source of anti-modular coupling between the implementations of unrelated WASI interfaces, with the net effect being that if you want to virtualize just one WASI interface that uses wasi-io, you end up being forced to virtualize/wrap them all.Additionally, for the same reason that wasi-io's
input-stream
andoutput-stream
want to use a single wasi-io-defined, payload-agnosticerror
resource type (instead of having each distinct WASI package define its own stream type with its own domain-specific error variant), I think Preview 3 async depends on there being a single C-M-levelerror
type (which you get when reading a stream and an error occurs). So if nothing else, I'd like to consider addingerror
in a Preview 3 timeframe, but if anyone was keen to work on this earlier, we could work on justerror
earlier.A few high-level open questions:
error
" canon built-in mentioned above, we might want it to just be a general structured logging function (that happens to takeerror
s). I think there'd be a lot of benefits to this too, but it does increase the problem scope... but maybe not too much? Alternatively, we could cut the other way and hold off on the "log anerror
" built-in (initially).error<P>
andstream<T,P>
whereP
was the error payload type, butP
was ignorable via subtyping rules sayingforall P. error<P> <: error
and similarlyforall P. stream<T,P> <: stream<T>
(noting that error payload values are not lost in these subtypings; just the static knowledge of their type). This would provide better static typing in common cases where you're directly consuming the result of, e.g., wasi-httpresource body { consume: func() -> result<stream<u8, error-code>>; }
. I'm not sure if it's worth the hassle to add this though and we could always add it backwards-compatibly later, so I'm inclined to leave it out (initially).There's a lot of details left to figure out (and maybe the basic sketch isn't right either), but I thought I'd file this now to collect thoughts and use cases.
The text was updated successfully, but these errors were encountered: