rpc icon indicating copy to clipboard operation
rpc copied to clipboard

Unions for response types to include errors

Open lpil opened this issue 4 years ago • 9 comments

Hello!

Very interested in this library! Looks very useful.

I'm interested in how you approach error handling with this library, but could not find any examples or docs.

Examples of errors might be resource not found for a given id, user not authenticated, user not authorized, etc.

Thanks, Louis

lpil avatar Jun 30 '20 23:06 lpil

It's a little half-baked at the moment, I'm thinking a ./errors pkg or similar (maybe still root) would be nice. Ideally all of the http status codes not just the few I special-cased here: https://github.com/apex/rpc/blob/master/error.go#L39-L56

But every error has to provide a human-friendly message and machine-friendly code so it ends up being say 400 { "type": "inavlid", "message": "The field 'title' is required" }, but I need to think more about conventions, and add a way to document them in the schema :D

Maybe since everything is generated, you should list them in the schema and these stubs are created for you to use in your handlers.

tj avatar Jul 01 '20 08:07 tj

I was wondering if unions could be used, so rather than having some kind of dedicated error handling we could say that a method (for example a get_user method) returns union(UserObject, NotFoundError, UnauthenticatedError)

It could be generally useful for more complex methods too.

lpil avatar Jul 01 '20 08:07 lpil

That could work, I'll give it some thought, in Go-land at least it would be more idiomatic to return error (unfortunately haha). I guess it either ends up being awkward for some languages in either case, Go people would be like WUTTTT I have to switch on a type??. I'll rename this so we can try to figure out if that would work

tj avatar Jul 01 '20 09:07 tj

I would have thought an error from the library would be that the transport failed, rather than it being a business logic error. It is tricky to draw the lines though.

One thing about using Go's error mechanism for all error cases is that it's no longer possible to return multiple errors, so people using this to drive a UI wouldn't be able to show all the validation problems to the user without rolling their own secondary error handling.

lpil avatar Jul 01 '20 09:07 lpil

True true, I did want to support arbitrary error context, just some object or whatever you want along-side type and message, but there's no reason that errors need to be standard across projects really. I'm definitely down with unions, but then we need a solution for languages that don't support unions — or don't support them well

tj avatar Jul 01 '20 09:07 tj

In Go would having an interface with the members documented be sufficient? I'm not sure how common it is to downcast from an interface

lpil avatar Jul 01 '20 09:07 lpil

It's totally doable in Go, but definitely not idiomatic, you pretty much never see a single interface value returned which acts as a union for errors as well. Maybe that will change once generics are introduced, but returning (value, error) is so wide-spread.

Maybe we can still treat errors in the schema as regular types, but have methods provide errors: [variants, here] so they're still separated from any result type. It's not quite as elegant, but languages with unions we could combine the result and error types, and for cases like Go it's still easy to separate them. Something like that haha.

tj avatar Jul 02 '20 14:07 tj

A success union and an error union could map well onto Go, languages with exceptions, and languages with a Result type. :)

Would network errors get automatically merged into the error union?

lpil avatar Jul 02 '20 14:07 lpil

Hmm I guess worst-case this package could just have an implicit type for network errors. I'll probably worry more about error handling in a month or two to polish this stuff up

tj avatar Jul 06 '20 08:07 tj