Stream: ideas

Topic: Modelling HTTP Status Codes


view this post on Zulip Luke Boswell (Dec 15 2024 at 22:47):

What do people think of this for modelling HTTP Status Codes?

https://developer.mozilla.org/en-US/docs/Web/HTTP/Status
https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml

Http.Status : [
    Success [Ok, Created, NoContent, Other U16],
    Redirect [MovedPermanently, Found, NotModified, Other U16],
    ClientErr [BadRequest, Unauthorized, Forbidden, NotFound, TooManyRequests, Other U16],
    ServerErr [InternalServerError, BadGateway, ServiceUnavailable, GatewayTimeout, Other U16],
]

view this post on Zulip Luke Boswell (Dec 15 2024 at 22:48):

Instead of giving a raw U16 and asking users to pattern match on that, we can provide more type safety.

view this post on Zulip Richard Feldman (Dec 15 2024 at 23:17):

I've never been a fan of that personally

view this post on Zulip Richard Feldman (Dec 15 2024 at 23:18):

I'm always like "I want to match on 401...which constant is that again? Unauthorized or Forbidden?"

view this post on Zulip Richard Feldman (Dec 15 2024 at 23:19):

etc.

view this post on Zulip Luke Boswell (Dec 15 2024 at 23:19):

Interesting... this is what I was thinking https://gist.github.com/lukewilliamboswell/0ad4474080714357e6b4200af397c0b0

view this post on Zulip Luke Boswell (Dec 15 2024 at 23:19):

I could add the number into the name, Ok200, BadRequest400, ...

view this post on Zulip Luke Boswell (Dec 15 2024 at 23:19):

Or add a helper as_u16: Status -> U16

view this post on Zulip Luke Boswell (Dec 15 2024 at 23:20):

Also can just leave it as raw U16... but then it's up the the app author to choose the correct numbers. Which is also Ok

view this post on Zulip Richard Feldman (Dec 15 2024 at 23:21):

I'm curious what others think, might just be my bias from having so many of the codes in muscle memory :sweat_smile:

view this post on Zulip Luke Boswell (Dec 15 2024 at 23:21):

I do think ClientErr BadRequest is clearer than 400 though when reading

view this post on Zulip Derin Eryilmaz (Dec 15 2024 at 23:31):

could you not just make functions is_success is_redirect is_client_err is_server_err ? (nvm i forgot bools are bad)

view this post on Zulip Derin Eryilmaz (Dec 15 2024 at 23:33):

or a function Http.status_type which does Status -> [Success, Redirect, ClientErr, ServerErr]

view this post on Zulip Luke Boswell (Dec 15 2024 at 23:44):

I've been trying to think about how it will be used in downstream code. This is an example of making a request using basic-cli.

# Basic HTTP GET request

main! = \{} ->

    response = Http.send! {
        method: Get,
        headers: [],
        url: "http://www.example.com",
        body: [],
        timeout: TimeoutMilliseconds 5000,
    }

    when response.status is
        Info _ -> Stdout.line! "Informational - Request received, continuing process."
        Success _ -> Stdout.line! "Success - The action was successfully received, understood, and accepted"
        Redirect _ -> Stdout.line! "Redirection - Further action must be taken in order to complete the request"
        ClientErr _ -> Stdout.line! "Client Error - The request contains bad syntax or cannot be fulfilled"
        ServerErr _ -> Stdout.line! "Server Error - The server failed to fulfill an apparently valid request"

My goal is to use the tags to be descriptive, and avoid function calls.

view this post on Zulip Luke Boswell (Dec 15 2024 at 23:45):

I'm missing Info... 1xx series... I'll add that too

edit: or maybe we don't need these... they look like intermediate status codes

view this post on Zulip Jasper Woudenberg (Dec 16 2024 at 07:47):

I also feel that I know the http numbers better than the status code names.

Seperately, I don't think I've ever ran into a situation where I wanted to exhaustively check all individual status codes of an http response, but maybe folks have different experiences. If users will not rely on exhaustiveness checking, then I don't think there's many benefits to expressing status codes as tags in terms of type-safety.

The one thing I have done is to check for ranges of status code responses, but for that use case ints are more flexible because you can easily differentiate between >= 400 to match all errors and >= 500 to match server errors, for instance.

view this post on Zulip Luke Boswell (Dec 16 2024 at 08:56):

Thank you @Jasper Woudenberg

I'm going to revert my changes in this PR https://github.com/roc-lang/basic-cli/blob/refactor/platform/InternalHttp.roc from this back to a U16.

I still think it's nice to model it like this, but I'd like to land these upgrades, and we don't need to solve this problem right now. it's easier to be conservative for now and leave it as it currently is. People can always model it in userland if they want type safety.

view this post on Zulip Anthony Bullard (Dec 16 2024 at 15:21):

I think a U16 makes sense for the API, but a module for StatusCodes that exposes the status codes as constants is very useful

view this post on Zulip Isaac Van Doren (Dec 22 2024 at 01:00):

I definitely prefer a number

view this post on Zulip Tobias Steckenborn (Jan 02 2025 at 06:46):

From my experience the names can be more useful, but it depends on the environment. It just helps to reason with others that might need to read or understand the code rarely (UX and the like). Given a proper logging solution you should anyways have the http status code logged as well. Where I'd agree is that when looking for the error it might happen that more people are looking for what's actually visible in the browser. So somehow the code should be included.


Last updated: Jun 16 2026 at 16:19 UTC