-
Notifications
You must be signed in to change notification settings - Fork 52
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
Use Result type from @polywrap/result instead of InvokeResult #1245
Comments
Related: #1018 |
Should the error in the Result type be an Error? or extend Error? Also, is Result really different from InvokeResult? It seems like InvokeResult provides the same functionality as Result, but in a more TypeScript-idiomatic way. |
Yah I'm a bit conflicted here... it is more "expensive" to pass around a |
I've been going through the core and replacing thrown exceptions with Result. I love the UX of Result and now I think it is a really positive change! I do still think the error type should be bounded to
What do you think? You're really talented and much more experienced than me, so I'm guessing you already thought about this a lot. Maybe you've already had this conversation lol. Also, is it okay if I go through the URI Resolvers and change the |
It should not extend Error. The error from result type can be anything (just a string, or an enum of errors, or a union of error strings etc.) depending on the needs of the user. Error (js Errors) are meant to be thrown, the error from the result type is not necessarily thrown (in fact, it enables recovering from errors). Actually, the Result type is more idiomatic which I think you've come to see from your comment below :) |
We already had a call on this topic, but I'll post the notes here to document them: enum InvokeErrorType {
UriNotFound = 1,
SubInvokeError = 2,
SomeOtherError 3,
}
const result = client.invoke<number, InvokeErrorType>(); Or with union strings: type InvokeErrorType = "UriNotFound" | "SubInvokeError" | "SomeOtherError";
const result = client.invoke<number, InvokeErrorType>(); Now that the errors are all accounted for, the user can safely and adequately recover from them. (E.g. with a switch(result.error) statement). As for the That all said, client.invoke could return the type |
I hear you, but after thinking about it for a couple of days I'm still unconvinced. You don't need to convince me, of course, but I want to make a case for the alternative. And of course I want to caveat everything I say with some humility: maybe I just don't understand it! First, I want to say I'm not opposed to I think this will cause unnecessary headaches: And I don't think this is feasible: It seems the generics approach would require users to know which type of error to expect. One URI resolver could be returning an enum, another a string, another an In Rust, users typically know what type of
I think it serves an important purpose! If you don't think it matters, do you mind if I change it to |
Yea, I can agree with that to an extent.
I think where most of the confusion comes from is that the current client doesn't manage errors all that well, and so the errors can be anything regardless of what the user configures. What I did with the unbounded generic type for error in the resolvers is moved the responsibility of the client's configuration to the user. It's only a small step in that direction. If every error extends Error | undefined, then you can't have the following: export type CustomError =
| "..."
| "...";
export class CustomResolver implements IUriResolver<CustomError> {
tryResolveUri(
uri: Uri
): Promise<Result<UriPackageOrWrapper, CustomError>> {
...
}
} This is an example of where the user can account for all the errors and uses a string union to define them (instead of the much heavier Error type). Of course, this is not possible with the invoke part of the client since there can be a lot of different error thrown. export interface ClientConfig<TUri extends Uri | string = string, TResolutionError> {
redirects: UriRedirect<TUri>[];
interfaces: InterfaceImplementations<TUri>[];
envs: Env<TUri>[];
resolver: IUriResolver<TResolutionError>;
} If we defined the Client like this, then users could still use any error type (like in the above example) if they want to implement their own version of the export class PolywrapClient implements Client<string, Error> {
...
} |
The InvokeResult type returned from invocations is defined as follows:
It should be replaced with the Result type from @polywrap/result to get better type checking from TypeScript
The text was updated successfully, but these errors were encountered: