From 9e0747db15282f6f8f8474f32e6b9ff0f1bf9174 Mon Sep 17 00:00:00 2001 From: Jack Fischer Date: Tue, 15 Nov 2016 19:37:40 -0500 Subject: [PATCH 1/2] Example for using error_handler --- examples/exception_monitoring.py | 59 ++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 examples/exception_monitoring.py diff --git a/examples/exception_monitoring.py b/examples/exception_monitoring.py new file mode 100644 index 00000000..51f8bfba --- /dev/null +++ b/examples/exception_monitoring.py @@ -0,0 +1,59 @@ +""" +Example intercepting uncaught exceptions using Sanic's error handler framework. + +This may be useful for developers wishing to use Sentry, Airbrake, etc. +or a custom system to log and monitor unexpected errors in production. + +First we create our own class inheriting from Handler in sanic.exceptions, +and pass in an instance of it when we create our Sanic instance. Inside this +class' default handler, we can do anything including sending exceptions to +an external service. +""" + + + +""" +Imports and code relevant for our CustomHandler class +(Ordinarily this would be in a separate file) +""" +from sanic.response import text +from sanic.exceptions import Handler, SanicException + +class CustomHandler(Handler): + def default(self, request, exception): + # Here, we have access to the exception object + # and can do anything with it (log, send to external service, etc) + + # Some exceptions are trivial and built into Sanic (404s, etc) + if not issubclass(type(exception), SanicException): + print(exception) + + # Then, we must finish handling the exception by + # returning our response to the client + return text("An error occured", status=500) + + + + +""" +This is an ordinary Sanic server, with the exception that we set the +server's error_handler to an instance of our CustomHandler +""" + +from sanic import Sanic +from sanic.response import json + +app = Sanic(__name__) + +handler = CustomHandler(sanic=app) +app.error_handler = handler + +@app.route("/") +async def test(request): + # Here, something occurs which causes an unexpected exception + # This exception will flow to our custom handler. + x = 1 / 0 + return json({"test": True}) + + +app.run(host="0.0.0.0", port=8000) From d9f6846c7641e6ae9c4ea4c688a4d24f56e83a8b Mon Sep 17 00:00:00 2001 From: Jack Fischer Date: Wed, 16 Nov 2016 07:55:54 -0500 Subject: [PATCH 2/2] improved default handling --- examples/exception_monitoring.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/examples/exception_monitoring.py b/examples/exception_monitoring.py index 51f8bfba..34b46a14 100644 --- a/examples/exception_monitoring.py +++ b/examples/exception_monitoring.py @@ -28,9 +28,10 @@ class CustomHandler(Handler): if not issubclass(type(exception), SanicException): print(exception) - # Then, we must finish handling the exception by - # returning our response to the client - return text("An error occured", status=500) + # Then, we must finish handling the exception by returning + # our response to the client + # For this we can just call the super class' default handler + return super.default(self, request, exception) @@ -56,4 +57,4 @@ async def test(request): return json({"test": True}) -app.run(host="0.0.0.0", port=8000) +app.run(host="0.0.0.0", port=8000, debug=True)