Skip to content

Commit

Permalink
fix: Move DRF custom exception handler to exceptions + support more…
Browse files Browse the repository at this point in the history
… types
  • Loading branch information
joolean committed Oct 25, 2023
1 parent 4eacd5a commit 7c79392
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 17 deletions.
40 changes: 40 additions & 0 deletions twitch_hdt_ebs/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import logging

import requests
from hearthsim.instrumentation.django_influxdb import write_point
from rest_framework import status
from rest_framework.exceptions import APIException
from rest_framework.views import exception_handler


class TwitchAPITimeout(APIException):
Expand All @@ -20,3 +25,38 @@ class BadGateway(APIException):
class BadTwitchResponse(BadGateway):
default_detail = "Twitch returned an invalid response."
default_code = "bad_twitch_response"


def untapped_django_exception_handler(exc, context):
"""A Django REST Framework "custom exception handler" for translating additional types.
This implementation attempts to convert upstream exception types corresponding to HTTP
502 (Bad gateway) and HTTP 504 (Gateway timeout) before delegating to the default
exception handler implementation.
See also
https://www.django-rest-framework.org/api-guide/exceptions/#custom-exception-handling
:param exc:
:param context:
"""

if isinstance(exc, requests.Timeout):
effective_exc = TwitchAPITimeout()
elif (
isinstance(exc, requests.ConnectionError) or
isinstance(exc, requests.HTTPError)
):
effective_exc = BadGateway()
else:
effective_exc = exc

detail = getattr(exc, "detail", {})

logger = logging.getLogger("twitch_hdt_ebs")
logger.error("Got exception %r, detail=%r", exc, detail)

if detail and isinstance(detail, dict):
write_point("api_error", {"count": 1}, error=detail.get("error", "unknown"))

return exception_handler(effective_exc, context)
2 changes: 1 addition & 1 deletion twitch_hdt_ebs/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ def get_deployment_uuid():
# Disable DRF browsable API (it requires templates to be setup)
REST_FRAMEWORK = {
"DEFAULT_RENDERER_CLASSES": ("rest_framework.renderers.JSONRenderer", ),
"EXCEPTION_HANDLER": "twitch_hdt_ebs.views.exception_handler",
"EXCEPTION_HANDLER": "twitch_hdt_ebs.exceptions.untapped_django_exception_handler",
}

# DRF CORS handling
Expand Down
16 changes: 0 additions & 16 deletions twitch_hdt_ebs/views.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import base64
import hashlib
import json
import logging
import string
from typing import Any, Dict, List, Optional

Expand Down Expand Up @@ -520,18 +519,3 @@ def get(self, request, user_id) -> Response:
class PingView(View):
def get(self, request):
return HttpResponse("OK", content_type="text/plain")


def exception_handler(exc, context):
from rest_framework.views import exception_handler as original_handler

response = original_handler(exc, context)
detail = getattr(exc, "detail", {})

logger = logging.getLogger("twitch_hdt_ebs")
logger.error("Got exception %r, detail=%r", exc, detail)

if detail and isinstance(detail, dict):
write_point("api_error", {"count": 1}, error=detail.get("error", "unknown"))

return response

0 comments on commit 7c79392

Please sign in to comment.