Skip to content

Conversation

wojtekmach
Copy link
Owner

@wojtekmach wojtekmach commented Jul 21, 2025

This is a replacement for https://hexdocs.pm/req/Req.Steps.html#handle_http_errors/1 which will be deprecated and removed in Req 1.0.

Some more context here:

In a nutshell:

- case Req.request(req) do
-   {:ok, %{status: 200}} = result ->
-     result
-
-   {:ok, resp} ->
-     exception =
-       RuntimeError.exception("""
-       unexpected status #{resp.status}
-
-       #{inspect(resp.body, pretty: true)}
-       """)
-
-     {:error, exception}
-
-   {:error, _} = error ->
-     error
- end
+ Req.request(req, expect: 200)

@@ -0,0 +1,16 @@
defmodule Req.UnexpectedResponseError do
defexception [:expected, :response]
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe instead of storing the full response we keep just:

Suggested change
defexception [:expected, :response]
defexception [:expected_status, :status, :headers, :body]

i.e. no resp.private (nor resp.assigns, #492)

@@ -0,0 +1,16 @@
defmodule Req.UnexpectedResponseError do
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

another idea for calling this:

Suggested change
defmodule Req.UnexpectedResponseError do
defmodule Req.UnexpectedResponseStatusError do

@wojtekmach
Copy link
Owner Author

Maybe we put it after decompress but before decode so the exception message just prints the string

@yordis
Copy link

yordis commented Jul 23, 2025

I still feel ok literally how Fetch Web API works is a good idea, along with expect thingy, and familiar to other ecosystems.

expect still extremely valuable to control the flow from the domain perspective, while ok is useful in the infra (steps) perspective for most use cases.

At least for most OpenAPI, non-redirecting APIs; which are the most commons anyway.

I think it is worth it to keep it around, and trivial enough where it doesn't add much complexity, if any.

@wojtekmach
Copy link
Owner Author

Thanks for the feedback about expect. I concede response.ok is ubiquitous due to being part of the Web platform.

I think in pattern matches, by the way of falling into another code branch that is for transport errors, expect "wins":

  case resp do
-   {:ok, %{ok?: true} = resp -> ...
-   {:ok, resp} -> ...
-   {:error, e} -> ...
+   {:ok, resp} ->
+   {:error, e} -> ...
  end

In other cases

- if resp.status in 200..299 do
+ if resp.ok? do

yeah, that looks really clean. My personal opinion though is it doesn't justify adding a new field to the struct even if that's some false scarcity argument.

@yordis
Copy link

yordis commented Jul 23, 2025

ok will always be 200..299 as the specs says, it is up the implementors to understand that behaviour. To be honest, the reason I keep coming back to this one (and I rather aligned here) is that it is such common case due to the popularity of JS and fetch.

Most likely useful for default steps behaviour and things like that, purely a semantic meaning that sometimes it is useful.

I have come across that 200..299 far too many times.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants