You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Resource types don't currently have the ability to define constructors as having custom result return error types.
For this reason, custom static constructors are likely usually preferable for resources since most constructor patterns with non-trivial arguments will want argument validation.
Would it make sense to consider result overloading only for resource constructors? I believe most languages should come with the ability to return an error from a resource constructor.
Great point and thanks for filing! This same issue came up in another context, with the same tentative conclusion, so agreed this is a good thing to add right after Preview 2. I think the change here is just to loosen the validation criteria for [constructor]-prefixed functions to additionally allow a return type of (result (own $R) (error T)) (for any T). With this, languages with new and exceptions can continue to have new call the constructor whereas other languages can emit the appropriate idiom for fallible constructors.
Reacted by Guy Bedford, Levente Morva, Landon James, Omar Tawfik and Jeff Simpson
I think this might be better than allowing constructor to return result<>, because languages such as JS cannot emit fallible constructors, but can admit fallible static methods that return this(). This allows making the constructor private and serving what some languages would call a smart constructor over the wire.
Sorry, I didn't follow your point regarding static methods, T, GuestT, and what's wrong with the workaround you showed?
because languages such as JS cannot emit fallible constructors
IIUC, the current prototyped JS bindings for result return types is that the failure case corresponds to an exception (with the result's error payload stored as a field on the exception object) and the success case just returns the success payload value directly (no wrapped with anything). Given this, a fallible constructor should I think map just fine to (throwing) new.
Is there any update on this?
I ran into a similar issue with a WIT interface for a resource that has a constructor that takes other resources and may fail.
I implemented import and export bindings for this component in Go but the best I can seem to do is return a ResourceNone (Rep 0) when the constructor fails and check this on the import side but I am unable to pass error information so the importer could log why it failed.
Seems like from above the workaround is to not use the built-in constructor but curious if this will change at some point.
I think everyone agrees this is a good idea and it's pretty easy to add to the spec and runtime (it just relaxes the validation predicate for [constructor] functions); mostly the work is just to generalize the bindings generators to be able to call and implement result-returning constructors. If anyone wants to work on this, please post here and I'm happy to write up the tiny spec PR. Otherwise, I think we'll naturally get to this after Preview 3 is released (perhaps along with getters/setters).
the work is just to generalize the bindings generators to be able to call and implement result-returning constructors. If anyone wants to work on this, please post here
I can take a stab at it. I assume what was said above (2 years ago) still holds today: in that the signature must either be constructor(...); or constructor(...) -> result<R,E>;
Activity
lukewagner commentedon Dec 11, 2023
Great point and thanks for filing! This same issue came up in another context, with the same tentative conclusion, so agreed this is a good thing to add right after Preview 2. I think the change here is just to loosen the validation criteria for
[constructor]-prefixed functions to additionally allow a return type of(result (own $R) (error T))(for anyT). With this, languages withnewand exceptions can continue to havenewcall the constructor whereas other languages can emit the appropriate idiom for fallible constructors.AaronFriel commentedon Mar 25, 2024
Static methods also return
Tinstead ofGuestT, so this workaround doesn't work:I think this might be better than allowing
constructorto returnresult<>, because languages such as JS cannot emit fallible constructors, but can admit fallible static methods that returnthis(). This allows making the constructor private and serving what some languages would call a smart constructor over the wire.lukewagner commentedon Mar 25, 2024
Sorry, I didn't follow your point regarding static methods,
T,GuestT, and what's wrong with the workaround you showed?IIUC, the current prototyped JS bindings for
resultreturn types is that the failure case corresponds to an exception (with theresult's error payload stored as a field on the exception object) and the success case just returns the success payload value directly (no wrapped with anything). Given this, a fallible constructor should I think map just fine to (throwing)new.result<>#436 as a duplicate of this issuejeff1010322 commentedon Jul 28, 2025
Is there any update on this?
I ran into a similar issue with a WIT interface for a resource that has a constructor that takes other resources and may fail.
I implemented import and export bindings for this component in Go but the best I can seem to do is return a ResourceNone (Rep 0) when the constructor fails and check this on the import side but I am unable to pass error information so the importer could log why it failed.
Seems like from above the workaround is to not use the built-in
constructorbut curious if this will change at some point.lukewagner commentedon Jul 28, 2025
I think everyone agrees this is a good idea and it's pretty easy to add to the spec and runtime (it just relaxes the validation predicate for
[constructor]functions); mostly the work is just to generalize the bindings generators to be able to call and implementresult-returning constructors. If anyone wants to work on this, please post here and I'm happy to write up the tiny spec PR. Otherwise, I think we'll naturally get to this after Preview 3 is released (perhaps along with getters/setters).badeend commentedon Aug 4, 2025
This just came up again in WebAssembly/wasi-sockets#128
I can take a stab at it. I assume what was said above (2 years ago) still holds today: in that the signature must either be
constructor(...);orconstructor(...) -> result<R,E>;lukewagner commentedon Aug 7, 2025
Awesome! I filed #550 for the spec PR.
badeend commentedon Aug 20, 2025
I've got the proposed changes (#550) working at:
wasm-tools: bytecodealliance/wasm-tools@main...badeend:wasm-tools:fallible-constructorswit-bindgen: bytecodealliance/wit-bindgen@main...badeend:wit-bindgen:fallible-constructorswasmtime: bytecodealliance/wasmtime@main...badeend:wasmtime:fallible-constructorswasmtime-wit-bindgenworked out of the box. All I've done here is add a codegen testcase.tcp/udp-socketresources from a staticcreatemethod to fallible constructor and all tests pass.What should the next steps be?
alexcrichton commentedon Aug 20, 2025
Nice! I think it's reasonable to PR those to each repo now and I can do a release of wasm-tools once that's merge so the other two can merge
badeend commentedon Aug 26, 2025
FYI, support for this has landed in wasm-tools, wit-bindgen & wasmtime
lukewagner commentedon Aug 26, 2025
Thanks for all the work on this! Can we close this issue as resolved?
badeend commentedon Aug 26, 2025
I'd say so, yes ✅