Skip to content

Provide a flexible concrete type for HTTPResponseError #602

@alephao

Description

@alephao

In hummingbird we can throw Swift Errors to halt a request handler. There are multiple instances of this pattern in hummingbird-examples repo. Hummingbird provides HTTPError as the default way to throw a valid HTTP Response, but the current implementation of HTTPType doesn't let us create a custom response body, the only possible format is to return a JSON with the structure {"message": "..."}.

The issue is that in real world projects, you'll probably want to return an HTML response, a custom JSON or something else, but to achieve this currently in hummingbird, you'll need to implement your own type conforming to HTTPResponseError or conform Response to HTTPResponseError.

So since using errors to halt execution of handlers is so common, the proposal here is for to hummingbird provide a way create a completely custom Response that can be thrown. Some options below:

Option 1. Conform Response to HTTPResponseError.

This was discussed briefly in the discord, and it seemed like a no-no, but I'm leaving it here for reference.

The idea is to just conform Response to HTTPResponseError so you can throw responses like throw Response(status: .badRequest) or throw SomeCodableType().response(...)

Option 2. Use a proxy type

We could create a proxy type for Response and conform it to HTTPResponseError. This provides the same flexibility of the Response type, but with a separation between a throwable and a non throwable type. We could initialize this type exactly the same as we would initialize a Response:

// Use same constructor as the Response type
throw ResponseError(status: .badRequest, headers: [:], body: nil)

// Pass a Response type
throw ResponseError(Response(/*....*/))

3. Expand HTTPError to accept a custom body

This is similar to option 2, but instead of creating a new type, we could expand the HTTPError type. I believe this would require some gymnastics to prevent breaking changes on 2.x, so would have to be looked into more carefully.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions