diff --git a/frappe/hooks.py b/frappe/hooks.py index 373f21b437..fd80ddbda3 100644 --- a/frappe/hooks.py +++ b/frappe/hooks.py @@ -31,6 +31,13 @@ app_include_js = [ "report.bundle.js", "telemetry.bundle.js", ] + +# JS code to include for error reporting +# This is only loaded if error reporting is enabled. +error_reporting_js = [ + "sentry.bundle.js", +] + app_include_css = [ "desk.bundle.css", "report.bundle.css", @@ -436,6 +443,7 @@ after_job = [ extend_bootinfo = [ "frappe.utils.telemetry.add_bootinfo", "frappe.core.doctype.user_permission.user_permission.send_user_permissions", + "frappe.utils.sentry.add_bootinfo", ] export_python_type_annotations = True diff --git a/frappe/public/js/sentry.bundle.js b/frappe/public/js/sentry.bundle.js new file mode 100644 index 0000000000..584e57c2ad --- /dev/null +++ b/frappe/public/js/sentry.bundle.js @@ -0,0 +1,6 @@ +import * as Sentry from "@sentry/browser"; + +Sentry.init({ + dsn: frappe.boot.sentry?.dsn, + release: frappe?.boot?.versions?.frappe, +}); diff --git a/frappe/utils/sentry.py b/frappe/utils/sentry.py new file mode 100644 index 0000000000..6ad110759c --- /dev/null +++ b/frappe/utils/sentry.py @@ -0,0 +1,21 @@ +import frappe + + +def add_bootinfo(bootinfo): + """Called from hook, sends DSN so client side can setup error monitoring. + + Config needs to be present in site_config in following format: + + "error_reporting": { + "sentry": { + "dsn": "...", + ... + } + } + """ + if not frappe.get_system_settings("auto_report_errors"): + return + + sentry_info = (frappe.conf.get("error_reporting") or {}).get("sentry") + if sentry_info: + bootinfo.sentry = sentry_info diff --git a/frappe/www/app.py b/frappe/www/app.py index 896587e461..2002bada96 100644 --- a/frappe/www/app.py +++ b/frappe/www/app.py @@ -47,6 +47,9 @@ def get_context(context): include_icons = hooks.get("app_include_icons", []) frappe.local.preload_assets["icons"].extend(include_icons) + if frappe.get_system_settings("auto_report_errors"): + include_js = hooks["error_reporting_js"] + include_js + context.update( { "no_cache": 1,