diff --git a/authentik/events/middleware.py b/authentik/events/middleware.py
index bb130cb02..58be17c06 100644
--- a/authentik/events/middleware.py
+++ b/authentik/events/middleware.py
@@ -12,6 +12,7 @@ from authentik.core.models import User
from authentik.events.models import Event, EventAction, Notification
from authentik.events.signals import EventNewThread
from authentik.events.utils import model_to_dict
+from authentik.lib.utils.errors import exception_to_string
class AuditMiddleware:
@@ -54,7 +55,14 @@ class AuditMiddleware:
# pylint: disable=unused-argument
def process_exception(self, request: HttpRequest, exception: Exception):
- """Unregister handlers in case of exception"""
+ """Disconnect handlers in case of exception"""
+ thread = EventNewThread(
+ EventAction.SYSTEM_EXCEPTION,
+ request,
+ message=exception_to_string(exception),
+ )
+ thread.run()
+
post_save.disconnect(dispatch_uid=LOCAL.authentik["request_id"])
pre_delete.disconnect(dispatch_uid=LOCAL.authentik["request_id"])
diff --git a/authentik/events/models.py b/authentik/events/models.py
index 7c35d9731..136bf79d3 100644
--- a/authentik/events/models.py
+++ b/authentik/events/models.py
@@ -71,6 +71,7 @@ class EventAction(models.TextChoices):
SYSTEM_TASK_EXECUTION = "system_task_execution"
SYSTEM_TASK_EXCEPTION = "system_task_exception"
+ SYSTEM_EXCEPTION = "system_exception"
CONFIGURATION_ERROR = "configuration_error"
diff --git a/authentik/lib/utils/errors.py b/authentik/lib/utils/errors.py
new file mode 100644
index 000000000..e2b210571
--- /dev/null
+++ b/authentik/lib/utils/errors.py
@@ -0,0 +1,10 @@
+"""error utils"""
+from traceback import format_tb
+
+TRACEBACK_HEADER = "Traceback (most recent call last):\n"
+
+
+def exception_to_string(exc: Exception) -> str:
+ """Convert exception to string stackrace"""
+ # Either use passed original exception or whatever we have
+ return TRACEBACK_HEADER + "".join(format_tb(exc.__traceback__)) + str(exc)
diff --git a/authentik/policies/process.py b/authentik/policies/process.py
index 36a6a3cf7..013de618f 100644
--- a/authentik/policies/process.py
+++ b/authentik/policies/process.py
@@ -1,7 +1,6 @@
"""authentik policy task"""
from multiprocessing import get_context
from multiprocessing.connection import Connection
-from traceback import format_tb
from typing import Optional
from django.core.cache import cache
@@ -11,12 +10,12 @@ from sentry_sdk.tracing import Span
from structlog.stdlib import get_logger
from authentik.events.models import Event, EventAction
+from authentik.lib.utils.errors import exception_to_string
from authentik.policies.exceptions import PolicyException
from authentik.policies.models import PolicyBinding
from authentik.policies.types import PolicyRequest, PolicyResult
LOGGER = get_logger()
-TRACEBACK_HEADER = "Traceback (most recent call last):\n"
FORK_CTX = get_context("fork")
PROCESS_CLASS = FORK_CTX.Process
@@ -106,11 +105,7 @@ class PolicyProcess(PROCESS_CLASS):
except PolicyException as exc:
# Either use passed original exception or whatever we have
src_exc = exc.src_exc if exc.src_exc else exc
- error_string = (
- TRACEBACK_HEADER
- + "".join(format_tb(src_exc.__traceback__))
- + str(src_exc)
- )
+ error_string = exception_to_string(src_exc)
# Create policy exception event, only when we're not debugging
if not self.request.debug:
self.create_event(EventAction.POLICY_EXCEPTION, message=error_string)
diff --git a/schema.yml b/schema.yml
index 1d38e7bc4..47b00675d 100644
--- a/schema.yml
+++ b/schema.yml
@@ -19153,6 +19153,7 @@ components:
- property_mapping_exception
- system_task_execution
- system_task_exception
+ - system_exception
- configuration_error
- model_created
- model_updated
diff --git a/web/src/locales/en.po b/web/src/locales/en.po
index 51b0aa61d..026cf7bfa 100644
--- a/web/src/locales/en.po
+++ b/web/src/locales/en.po
@@ -1391,6 +1391,7 @@ msgstr "Event {0}"
msgid "Events"
msgstr "Events"
+#: src/pages/events/EventInfo.ts
#: src/pages/events/EventInfo.ts
#: src/pages/events/EventInfo.ts
msgid "Exception"
@@ -2497,6 +2498,10 @@ msgstr "Only send notification once, for example when sending a webhook into a c
msgid "Open application"
msgstr "Open application"
+#: src/pages/events/EventInfo.ts
+msgid "Open issue on GitHub..."
+msgstr "Open issue on GitHub..."
+
#: src/pages/providers/oauth2/OAuth2ProviderViewPage.ts
msgid "OpenID Configuration Issuer"
msgstr "OpenID Configuration Issuer"
diff --git a/web/src/locales/pseudo-LOCALE.po b/web/src/locales/pseudo-LOCALE.po
index 6df2b473c..cd3732266 100644
--- a/web/src/locales/pseudo-LOCALE.po
+++ b/web/src/locales/pseudo-LOCALE.po
@@ -1383,6 +1383,7 @@ msgstr ""
msgid "Events"
msgstr ""
+#:
#:
#:
msgid "Exception"
@@ -2489,6 +2490,10 @@ msgstr ""
msgid "Open application"
msgstr ""
+#:
+msgid "Open issue on GitHub..."
+msgstr ""
+
#:
msgid "OpenID Configuration Issuer"
msgstr ""
diff --git a/web/src/pages/events/EventInfo.ts b/web/src/pages/events/EventInfo.ts
index 4b61e04cd..19e7088e2 100644
--- a/web/src/pages/events/EventInfo.ts
+++ b/web/src/pages/events/EventInfo.ts
@@ -7,11 +7,12 @@ import "../../elements/Expand";
import { PFSize } from "../../elements/Spinner";
import { EventContext, EventWithContext } from "../../api/Events";
import { DEFAULT_CONFIG } from "../../api/Config";
-
+import PFButton from "@patternfly/patternfly/components/Button/button.css";
import PFDescriptionList from "@patternfly/patternfly/components/DescriptionList/description-list.css";
import PFFlex from "@patternfly/patternfly/layouts/Flex/flex.css";
import PFBase from "@patternfly/patternfly/patternfly-base.css";
import PFList from "@patternfly/patternfly/components/List/list.css";
+import { VERSION } from "../../constants";
@customElement("ak-event-info")
export class EventInfo extends LitElement {
@@ -20,7 +21,7 @@ export class EventInfo extends LitElement {
event!: EventWithContext;
static get styles(): CSSResult[] {
- return [PFBase, PFFlex, PFList, PFDescriptionList,
+ return [PFBase, PFButton, PFFlex, PFList, PFDescriptionList,
css`
code {
display: block;
@@ -137,6 +138,45 @@ export class EventInfo extends LitElement {
`;
}
+ buildGitHubIssueUrl(title: string, body: string): string {
+ // https://docs.github.com/en/issues/tracking-your-work-with-issues/creating-issues/about-automation-for-issues-and-pull-requests-with-query-parameters
+ const fullBody = `
+**Describe the bug**
+A clear and concise description of what the bug is.
+
+**To Reproduce**
+Steps to reproduce the behavior:
+1. Go to '...'
+2. Click on '....'
+3. Scroll down to '....'
+4. See error
+
+**Expected behavior**
+A clear and concise description of what you expected to happen.
+
+**Screenshots**
+If applicable, add screenshots to help explain your problem.
+
+**Logs**
+Stacktrace from authentik
+
+\`\`\`
+${body}
+\`\`\`
+
${this.event.context.message}
+