-
-
Notifications
You must be signed in to change notification settings - Fork 414
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
Allow endpoints to advertise returnable errors #349
Comments
I think a better approach would be to derive possible errors from the combinators used. type API = AuthProtected "auth-cookie" :> "foo" :> ReqBody '[JSON] Foo :> Post '[] () We know that authentication or request body can fail. I think this should be the preferred approach. But sometimes I guess data ExtraErrorResponse status description
instance HasServer api => HasServer (ExtraErrorResponse s d :> api) where
type ServerT (ExtraErrorResponse s d :> api) = ServerT api
route _ = route (Proxy :: Proxy api)
instance (KnownNat s, KnownSymbol d, HasSwagger api)
=> HasSwagger (ExtraErrorResponse s d :> api) where
toSwagger _ = toSwagger (Proxy :: Proxy api)
& addResponse status response
where
status = natVal (Proxy :: Proxy s)
response = mempty
& responseDescription .~ Text.pack (symbolVal (Proxy :: Proxy d)) Here's how it can be used for you example: type family api `WithErrors` errors where
api `WithErrors` '[] = api
api `WithErrors` (e ': es) = (e :> api) `WithErrors es
type AuthError = ExtraErrorResponse 403 "Forbidden"
type InvalidFoo = ExtraErrorResponse 400 "Invalid foo"
type CommonErrors = '[AuthError, InvalidFoo]
type MyAPI = "foo" :> Get '[JSON] Foo `WithErrors` CommonErrors I didn't check any of this code with GHC, though I'm pretty sure it should work. |
Yes, if there was a way to allow combinators to carry along some context that they can cause a certain type of error, that would be the bee's knees. |
There's no safety in this, in the sense that other errors may show up, and those may actually be impossible. Not necessarily damning though, since that's already more or less what happens. We did talk about fixing that a while ago though (some thoughts here); it might be interesting to revisit it. |
@dredozubov in #500 : I don't know if it was discussed before, but here's my five cents. Errors are currently produced by the ServantErr record and it would be nice to parametrize it with and error type(and possibly type-level http codes with Nat!) to expose them in an API types:
I think it makes a lot of sense, because you can have nice structured errors this way(imagine you have some validation errors which result in the nested json structure). Of course it'll be necessary to add some type-level combinators to make this kind of declarations. For those of you who'll think "just use a sum type for the result API type" - i don't think it captures the http semantics well. You'll have to answer with a error and http code 200 OK this way. It'll force the changes in one of the two directions:
But if it comes this way, it'll be possible to infer all possible(tbh except the parse errors) http codes and error types from the API type. |
Duplicates #841 |
Indeed. |
When I define an API, I can only advertise what it should return in the success case. But in most cases I also want to be able to tell the user what errors they can expect; for example, a 403 representing auth failure or a 422 representing invalid request data.
I'm not sure how this could be done in practice. My first idea was something like this:
and
(though I'm not even sure that code is either possible or logically correct).
Among other things, this could greatly simplify documentation generation.
The text was updated successfully, but these errors were encountered: