elixir-grpc / grpc

An Elixir implementation of gRPC
https://hex.pm/packages/grpc
Apache License 2.0
1.36k stars 210 forks source link

Server Side Error Reports #349

Open matthewberends opened 4 months ago

matthewberends commented 4 months ago

Describe the question We use bugsnag to report any crashes that occur. Bugsnag uses SASL reports to automatically report process crashes. However with elixir-grpc they do not get reported.

We currently have to maintain a fork of elixir-grpc which will re-raise any errors that occur so that the error reports are created and thus reported to bugsnag.

For example in cowboy/handler.ex:

# unknown error raised from rpc
def info({:EXIT, pid, {:handle_error, e}}, req, _state = %{pid: pid}) do
  error = %RPCError{status: GRPC.Status.unknown(), message: "Internal Server Error"}
  trailers = HTTP2.server_trailers(error.status, error.message)
  exit_handler(pid, :error)
  req = send_error_trailers(req, trailers)
  error = HandlerError.exception(req: req, kind: e.kind, reason: e.reason, stack: e.stack)
  HandlerError.reraise(error)
end

as opposed to

def info({:EXIT, pid, {:handle_error, _kind}}, req, state = %{pid: pid}) do
  error = %RPCError{status: GRPC.Status.unknown(), message: "Internal Server Error"}
  trailers = HTTP2.server_trailers(error.status, error.message)
  exit_handler(pid, :error)
  req = send_error_trailers(req, trailers)
  {:stop, req, state}
end

This is our only difference in our fork from the upstream and would love to have services use the upstream directly. We attempted to mimic this behaviour using a server interceptor. This partially works as we can capture any errors that happen in our server implementations, but any errors that occur while trying to send the actually message (network, protobuf encoding) are not available to interceptors as interceptors are invoked before hand.

Are there any recommendations on how to handle this?

One potential solution to this could be to support a callback in the error handling code that users could set to allow some additional flexibility.