diff --git a/passbook/flows/templates/flows/error.html b/passbook/flows/templates/flows/error.html
new file mode 100644
index 000000000..9f549077c
--- /dev/null
+++ b/passbook/flows/templates/flows/error.html
@@ -0,0 +1,22 @@
+{% load i18n %}
+
+
+
+
+
+ {% trans 'Whoops!' %}
+
+
+
+
+ {% trans 'Something went wrong! Please try again later.' %}
+
+ {% if debug %}
+
{{ tb }}
+ {% endif %}
+
diff --git a/passbook/flows/views.py b/passbook/flows/views.py
index bbe010392..0e6d0fef5 100644
--- a/passbook/flows/views.py
+++ b/passbook/flows/views.py
@@ -1,4 +1,5 @@
"""passbook multi-stage authentication engine"""
+from traceback import format_tb
from typing import Any, Dict, Optional
from django.http import (
@@ -8,7 +9,7 @@ from django.http import (
HttpResponseRedirect,
JsonResponse,
)
-from django.shortcuts import get_object_or_404, redirect, reverse
+from django.shortcuts import get_object_or_404, redirect, render, reverse
from django.template.response import TemplateResponse
from django.utils.decorators import method_decorator
from django.views.decorators.clickjacking import xframe_options_sameorigin
@@ -106,8 +107,18 @@ class FlowExecutorView(View):
stage=self.current_stage,
flow_slug=self.flow.slug,
)
- stage_response = self.current_stage_view.get(request, *args, **kwargs)
- return to_stage_response(request, stage_response)
+ try:
+ stage_response = self.current_stage_view.get(request, *args, **kwargs)
+ return to_stage_response(request, stage_response)
+ except Exception as exc: # pylint: disable=broad-except
+ return to_stage_response(
+ request,
+ render(
+ request,
+ "flows/error.html",
+ {"error": exc, "tb": "".join(format_tb(exc.__traceback__)),},
+ ),
+ )
def post(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
"""pass post request to current stage"""
@@ -117,8 +128,18 @@ class FlowExecutorView(View):
stage=self.current_stage,
flow_slug=self.flow.slug,
)
- stage_response = self.current_stage_view.post(request, *args, **kwargs)
- return to_stage_response(request, stage_response)
+ try:
+ stage_response = self.current_stage_view.post(request, *args, **kwargs)
+ return to_stage_response(request, stage_response)
+ except Exception as exc: # pylint: disable=broad-except
+ return to_stage_response(
+ request,
+ render(
+ request,
+ "flows/error.html",
+ {"error": exc, "tb": "".join(format_tb(exc.__traceback__)),},
+ ),
+ )
def _initiate_plan(self) -> FlowPlan:
planner = FlowPlanner(self.flow)