Skip to content

Commit d145f5f

Browse files
ShahanaFarooquicdecker
authored andcommitted
grpcweb: Error Handling
1 parent 5aa2f17 commit d145f5f

File tree

1 file changed

+35
-12
lines changed

1 file changed

+35
-12
lines changed

libs/gl-testing/gltesting/grpcweb.py

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,13 @@
88

99
from gltesting.scheduler import Scheduler
1010
from ephemeral_port_reserve import reserve
11-
from threading import Thread, Event
11+
from threading import Thread
1212
from http.server import ThreadingHTTPServer, BaseHTTPRequestHandler
1313
import logging
1414
import struct
1515
import httpx
1616
from dataclasses import dataclass
1717
from typing import Dict
18-
import ssl
19-
2018

2119
class GrpcWebProxy(object):
2220
def __init__(self, scheduler: Scheduler, grpc_port: int):
@@ -67,6 +65,7 @@ class Request:
6765
@dataclass
6866
class Response:
6967
body: bytes
68+
headers: Dict[str, str]
7069

7170

7271
class Handler(BaseHTTPRequestHandler):
@@ -91,9 +90,10 @@ def proxy(self, request) -> Response:
9190
headers=headers,
9291
content=content,
9392
)
94-
client = httpx.Client(http1=False, http2=True)
93+
timeout = httpx.Timeout(10.0, connect=5.0)
94+
client = httpx.Client(http1=False, http2=True, timeout=timeout)
9595
res = client.send(req)
96-
return Response(body=res.content)
96+
return Response(body=res.content, headers=res.headers)
9797

9898
def auth(self, request: Request) -> bool:
9999
"""Authenticate the request. True means allow."""
@@ -118,11 +118,18 @@ def do_POST(self):
118118

119119
req = Request(body=body, headers=self.headers, flags=flags, length=length)
120120
if not self.auth(req):
121-
self.wfile.write(b"HTTP/1.1 401 Unauthorized\r\n\r\n")
121+
self.send_response(401)
122+
self.send_header("Content-Type", "application/grpc")
123+
self.send_header("grpc-status", "16")
124+
self.end_headers()
125+
self.wfile.write(b"Unauthorized")
122126
return
123-
127+
124128
response = self.proxy(req)
125-
self.wfile.write(b"HTTP/1.0 200 OK\n\n")
129+
self.send_response(200)
130+
self.send_header("Content-Type", "application/grpc")
131+
self.send_header("grpc-status", response.headers.get("grpc-status", "0"))
132+
self.end_headers()
126133
self.wfile.write(response.body)
127134
self.wfile.flush()
128135

@@ -203,7 +210,23 @@ def proxy(self, request: Request):
203210
headers=headers,
204211
content=content,
205212
)
206-
res = client.send(req)
207-
208-
# Return response
209-
return Response(body=res.content)
213+
214+
try:
215+
res = client.send(req)
216+
# Capture the error from header and send it in the body as well
217+
if res.headers.get("grpc-status", "0") != "0":
218+
grpc_status = res.headers.get("grpc-status")
219+
error_message = res.headers.get("grpc-message", "None")
220+
self.logger.warning(f"gRPC status code received: {grpc_status}")
221+
self.logger.warning(f"gRPC message received: {error_message}")
222+
error = error_message.encode("utf-8")
223+
error_res = struct.pack("!cI", request.flags, len(error)) + error
224+
return Response(body=error_res, headers=res.headers)
225+
# Return successful response
226+
return Response(body=res.content, headers=res.headers)
227+
except Exception as e:
228+
self.logger.warning(f"gRPC request error received: {str(e)}")
229+
error_message = f"Internal Server Error: {str(e)}"
230+
error = error_message.encode("utf-8")
231+
error_res = struct.pack("!cI", request.flags, len(error)) + error
232+
return Response(body=error_res, headers={"Content-Type": "application/grpc", "grpc-status": "13"})

0 commit comments

Comments
 (0)