diff --git a/lib/grpc/server/adapters/cowboy/handler.ex b/lib/grpc/server/adapters/cowboy/handler.ex index f0f5641b..c21a3479 100644 --- a/lib/grpc/server/adapters/cowboy/handler.ex +++ b/lib/grpc/server/adapters/cowboy/handler.ex @@ -376,6 +376,12 @@ defmodule GRPC.Server.Adapters.Cowboy.Handler do result = server.__call_rpc__(path, stream) case result do + {:ok, _stream, error = %GRPC.RPCError{message: nil, status: status}} -> + {:error, %{error | message: GRPC.Status.status_message(status)}} + + {:ok, _stream, error = %GRPC.RPCError{}} -> + {:error, error} + {:ok, stream, response} -> stream |> GRPC.Server.send_reply(response) diff --git a/test/grpc/integration/server_test.exs b/test/grpc/integration/server_test.exs index 378a6754..53af4a52 100644 --- a/test/grpc/integration/server_test.exs +++ b/test/grpc/integration/server_test.exs @@ -60,6 +60,19 @@ defmodule GRPC.Integration.ServerTest do raise "unknown error(This is a test, please ignore it)" end + def say_hello(%{name: "handled error"}, _stream) do + %GRPC.RPCError{ + status: GRPC.Status.unauthenticated(), + message: "Please authenticate" + } + end + + def say_hello(%{name: "handled error without message"}, _stream) do + %GRPC.RPCError{ + status: GRPC.Status.unauthenticated() + } + end + def say_hello(_req, _stream) do raise GRPC.RPCError, status: GRPC.Status.unauthenticated(), message: "Please authenticate" end @@ -172,6 +185,32 @@ defmodule GRPC.Integration.ServerTest do end) end + test "return errors for handled errors" do + run_server([HelloErrorServer], fn port -> + {:ok, channel} = GRPC.Stub.connect("localhost:#{port}") + req = Helloworld.HelloRequest.new(name: "handled error") + {:error, reply} = channel |> Helloworld.Greeter.Stub.say_hello(req) + + assert %GRPC.RPCError{ + status: GRPC.Status.unauthenticated(), + message: "Please authenticate" + } == reply + end) + end + + test "return errors for handled errors with the default message of the status" do + run_server([HelloErrorServer], fn port -> + {:ok, channel} = GRPC.Stub.connect("localhost:#{port}") + req = Helloworld.HelloRequest.new(name: "handled error without message") + {:error, reply} = channel |> Helloworld.Greeter.Stub.say_hello(req) + + assert %GRPC.RPCError{ + status: GRPC.Status.unauthenticated(), + message: "The request does not have valid authentication credentials for the operation" + } == reply + end) + end + test "returns appropriate error for stream requests" do run_server([FeatureErrorServer], fn port -> {:ok, channel} = GRPC.Stub.connect("localhost:#{port}")