getsentry/sentry-elixir

Simplify a way to obtain rate limits headers

up2jj opened this issue · 5 comments

Currently there is no simple way to get rate limits as they are returned by sdk in form of response headers (as described here: https://docs.sentry.io/api/ratelimits/#headers).
When I tried to send a request, I have got a normalized, simplified response:

iex(node@node)4> Sentry.capture_message("test", result: :sync)

12:45:56.559 [warning] Failed to send Sentry event. Error in HTTP Request to Sentry - "Received 429 from Sentry server: "
{:error, {:request_failure, "Received 429 from Sentry server: "}}

There should be some programmatic way to either get rate limits or return full response with headers.

That's a good callout. We can introduce a new Sentry-specific exception for when reporting errors fails.

defmodule Sentry.SendError do
  defexception [...]
end

Sentry.capture_message/2 and friends are already documented to return {:error, term()}, so this doesn't break any contract.

@savhappy will work on this.

After thinking about this some more, I think we can introduce a Sentry.ClientError exception instead. It would be returned by Sentry.Client if the HTTP request fails.

defmodule Sentry.ClientError do
  @moduledoc """
  ...
  """

  @moduledoc since: "10.7.0"

  @type t() :: %__MODULE__{...}

  defexception [:reason]
end

The possible errors that we have now (and that would go into :reason above), as far as I could quickly tell, are:

  • {:invalid_json, reason}
  • :too_many_retries
  • {Exception.kind(), data, stacktrace}
  • {:server_error, http_status, error_header_value}

We should also document these in the t() type above and the moduledoc.

Thanks for the above comment @whatyouhide! I have a PR out that matches on errors returned from sending the result in Client.send_event/2.

@savhappy now that we have the new error, I think we can add a new error reason: :server_error. Then, we can add two more fields to the exception, so that it becomes this:

@type t() :: %__MODULE__{
  reason: reason(),
  http_response: nil | {status :: 100..199, headers :: [{String.t, String.t}], body :: binary()},
}

Basically, the new http_response field would be nil for errors that are not from the server (like timeouts, or invalid request JSON) but it would be {status, headers, body} when the Sentry server returns a response. This would solve this particular issue, where @up2jj is asking for a way to programmatically access the rate limit headers that Sentry returns.

Thoughts?

Yep yep @whatyouhide , this is perfect, I'll add it in!