Skip to content

Commit 0889390

Browse files
committed
fix: handle backend errors on GET
Handle errors from backend, for example Unauthorized if an invalid API token was configured, gracefully instead of logging a traceback and leaving the client with an internal server error. Signed-off-by: Georg Pfuetzenreuter <mail@georg-pfuetzenreuter.net>
1 parent 53f6971 commit 0889390

File tree

3 files changed

+65
-7
lines changed

3 files changed

+65
-7
lines changed

powerdns_api_proxy/models.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,18 @@ def __init__(self):
231231
self.detail = "Metrics not allowed"
232232

233233

234+
class UpstreamException(HTTPException):
235+
def __init__(self):
236+
self.status_code = 500
237+
self.detail = "Error while connecting to PowerDNS backend"
238+
239+
240+
class UnhandledException(HTTPException):
241+
def __init__(self):
242+
self.status_code = 500
243+
self.detail = "Unhandled error"
244+
245+
234246
class RRSETRecord(TypedDict):
235247
content: str
236248
disabled: bool

powerdns_api_proxy/pdns.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ def __init__(self, url: str, token: str, verify_ssl: bool = True):
99
self.token = token
1010
self.verify_ssl = verify_ssl
1111
self.headers = {
12+
"Accept": "application/json",
1213
"Content-Type": "application/json",
1314
"X-API-Key": self.token,
1415
}

powerdns_api_proxy/proxy.py

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
ResponseZoneAllowed,
3131
RessourceNotAllowedException,
3232
SearchNotAllowedException,
33+
UnhandledException,
34+
UpstreamException,
3335
ZoneAdminNotAllowedException,
3436
ZoneNotAllowedException,
3537
)
@@ -185,7 +187,13 @@ async def get_servers(response: Response):
185187
req = await pdns.get("/api/v1/servers")
186188
data = await req.json()
187189
response.status_code = req.status
188-
return data
190+
191+
if response.status_code == HTTPStatus.OK:
192+
return data
193+
elif 'error' in data:
194+
raise UpstreamException()
195+
else:
196+
raise UnhandledException()
189197

190198

191199
@router_pdns.get("/servers/{server_id}")
@@ -198,7 +206,13 @@ async def get_server(response: Response, server_id: str):
198206
resp = await pdns.get(f"/api/v1/servers/{server_id}")
199207
data = await response_json_or_text(resp)
200208
response.status_code = resp.status
201-
return data
209+
210+
if response.status_code == HTTPStatus.OK:
211+
return data
212+
elif 'error' in data:
213+
raise UpstreamException()
214+
else:
215+
raise UnhandledException()
202216

203217

204218
@router_pdns.get(
@@ -249,7 +263,13 @@ async def get_zones(
249263
)
250264
response.status_code = resp.status
251265
zones = await resp.json()
252-
return get_only_pdns_zones_allowed(environment, zones)
266+
267+
if response.status_code == HTTPStatus.OK:
268+
return get_only_pdns_zones_allowed(environment, zones)
269+
elif 'error' in zones:
270+
raise UpstreamException()
271+
else:
272+
raise UnhandledException()
253273

254274

255275
@router_pdns.post(
@@ -301,7 +321,13 @@ async def get_zone_metadata(
301321
)
302322
response.status_code = resp.status
303323
data = await response_json_or_text(resp)
304-
return data
324+
325+
if response.status_code == HTTPStatus.OK:
326+
return data
327+
elif 'error' in data:
328+
raise UpstreamException()
329+
else:
330+
raise UnhandledException()
305331

306332

307333
@router_pdns.put("/servers/{server_id}/zones/{zone_id}")
@@ -440,7 +466,13 @@ async def search_data(
440466
)
441467
response.status_code = resp.status
442468
data = await response_json_or_text(resp)
443-
return data
469+
470+
if response.status_code == HTTPStatus.OK:
471+
return data
472+
elif 'error' in data:
473+
raise UpstreamException()
474+
else:
475+
raise UnhandledException()
444476

445477

446478
@router_pdns.get("/servers/{server_id}/tsigkeys")
@@ -457,7 +489,13 @@ async def list_tsigkeys(response: Response, server_id: str, X_API_Key: str = Hea
457489
resp = await pdns.get(f"/api/v1/servers/{server_id}/tsigkeys")
458490
response.status_code = resp.status
459491
data = await response_json_or_text(resp)
460-
return data
492+
493+
if response.status_code == HTTPStatus.OK:
494+
return data
495+
elif 'error' in data:
496+
raise UpstreamException()
497+
else:
498+
raise UnhandledException()
461499

462500

463501
@router_pdns.get("/servers/{server_id}/tsigkeys/{tsigkey_id}")
@@ -476,7 +514,14 @@ async def fetch_tsigkey(
476514
resp = await pdns.get(f"/api/v1/servers/{server_id}/tsigkeys/{tsigkey_id}")
477515
response.status_code = resp.status
478516
data = await response_json_or_text(resp)
479-
return data
517+
518+
if response.status_code == HTTPStatus.OK:
519+
return data
520+
elif 'error' in data:
521+
raise UpstreamException()
522+
else:
523+
raise UnhandledException()
524+
480525

481526

482527
@router_pdns.post("/servers/{server_id}/tsigkeys")

0 commit comments

Comments
 (0)