@@ -155,24 +155,59 @@ defmodule GRPC.Client.Adapters.Gun do
155155 ) do
156156 % { channel: % { adapter_payload: adapter_payload } , payload: payload } = stream
157157
158- with { :ok , headers , is_fin } <- recv_headers ( adapter_payload , payload , opts ) do
159- response = response_stream ( is_fin , stream , opts )
158+ case recv_headers ( adapter_payload , payload , opts ) do
159+ { :ok , headers , :fin } ->
160+ handle_fin_response ( headers , opts )
160161
161- if ( opts [ :return_headers ] ) do
162- { :ok , response , % { headers: headers } }
163- else
164- { :ok , response }
165- end
162+ { :ok , headers , :nofin } ->
163+ handle_streaming_nofin_response ( stream , headers , opts )
164+
165+ { :error , _ } = error ->
166+ error
166167 end
167168 end
168169
169170 def receive_data ( stream , opts ) do
170171 % { payload: payload , channel: % { adapter_payload: adapter_payload } } = stream
171172
172- with { :ok , headers , _is_fin } <- recv_headers ( adapter_payload , payload , opts ) ,
173- { :ok , body , trailers } <- recv_body ( adapter_payload , payload , opts ) ,
173+ case recv_headers ( adapter_payload , payload , opts ) do
174+ { :ok , headers , :fin } ->
175+ handle_fin_response ( headers , opts )
176+
177+ { :ok , headers , :nofin } ->
178+ handle_nofin_response ( adapter_payload , payload , stream , headers , opts )
179+
180+ { :error , _ } = error ->
181+ error
182+ end
183+ end
184+
185+ defp handle_fin_response ( headers , opts ) do
186+ # Trailers-only response: headers contain trailers, check status
187+ with :ok <- parse_trailers ( headers ) do
188+ if opts [ :return_headers ] do
189+ { :ok , [ ] , % { headers: headers } }
190+ else
191+ { :ok , [ ] }
192+ end
193+ end
194+ end
195+
196+ defp handle_streaming_nofin_response ( stream , headers , opts ) do
197+ response = response_stream ( :nofin , stream , opts )
198+
199+ if opts [ :return_headers ] do
200+ { :ok , response , % { headers: headers } }
201+ else
202+ { :ok , response }
203+ end
204+ end
205+
206+ defp handle_nofin_response ( adapter_payload , payload , stream , headers , opts ) do
207+ # Regular response: fetch body and trailers
208+ with { :ok , body , trailers } <- recv_body ( adapter_payload , payload , opts ) ,
174209 { :ok , response } <- parse_response ( stream , headers , body , trailers ) do
175- if ( opts [ :return_headers ] ) do
210+ if opts [ :return_headers ] do
176211 { :ok , response , % { headers: headers , trailers: trailers } }
177212 else
178213 { :ok , response }
@@ -230,25 +265,7 @@ defmodule GRPC.Client.Adapters.Gun do
230265 { :response , :fin , status , headers } ->
231266 if status == 200 do
232267 headers = GRPC.Transport.HTTP2 . decode_headers ( headers )
233-
234- case headers [ "grpc-status" ] do
235- nil ->
236- { :error ,
237- GRPC.RPCError . exception (
238- GRPC.Status . internal ( ) ,
239- "shouldn't finish when getting headers"
240- ) }
241-
242- "0" ->
243- { :response , headers , :fin }
244-
245- _ ->
246- { :error ,
247- GRPC.RPCError . exception (
248- String . to_integer ( headers [ "grpc-status" ] ) ,
249- headers [ "grpc-message" ]
250- ) }
251- end
268+ { :response , headers , :fin }
252269 else
253270 { :error ,
254271 GRPC.RPCError . exception (
@@ -260,16 +277,7 @@ defmodule GRPC.Client.Adapters.Gun do
260277 { :response , :nofin , status , headers } ->
261278 if status == 200 do
262279 headers = GRPC.Transport.HTTP2 . decode_headers ( headers )
263-
264- if headers [ "grpc-status" ] && headers [ "grpc-status" ] != "0" do
265- { :error ,
266- GRPC.RPCError . exception (
267- String . to_integer ( headers [ "grpc-status" ] ) ,
268- headers [ "grpc-message" ]
269- ) }
270- else
271- { :response , headers , :nofin }
272- end
280+ { :response , headers , :nofin }
273281 else
274282 { :error ,
275283 GRPC.RPCError . exception (
@@ -349,8 +357,6 @@ defmodule GRPC.Client.Adapters.Gun do
349357 end
350358 end
351359
352- defp response_stream ( :fin , _stream , _opts ) , do: [ ]
353-
354360 defp response_stream (
355361 :nofin ,
356362 % {
@@ -453,7 +459,14 @@ defmodule GRPC.Client.Adapters.Gun do
453459 if status == GRPC.Status . ok ( ) do
454460 :ok
455461 else
456- { :error , % GRPC.RPCError { status: status , message: trailers [ "grpc-message" ] } }
462+ rpc_error =
463+ GRPC.RPCError . from_grpc_status_details_bin ( % {
464+ status: status ,
465+ message: trailers [ "grpc-message" ] ,
466+ encoded_details_bin: trailers [ "grpc-status-details-bin" ]
467+ } )
468+
469+ { :error , rpc_error }
457470 end
458471 end
459472
0 commit comments