Add minor improvements to error reporting (#8402)

This commit is contained in:
Andrey Antukh 2026-03-04 09:12:19 +01:00 committed by GitHub
parent b704a7da0e
commit a4351d133b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 54 additions and 38 deletions

View File

@ -8,7 +8,6 @@ Report: {{hint|abbreviate:150}} - {{id}} - Penpot Error Report (v4)
<nav> <nav>
<div>[<a href="/dbg/error?version={{version}}">⮜</a>]</div> <div>[<a href="/dbg/error?version={{version}}">⮜</a>]</div>
<div>[<a href="#head">head</a>]</div> <div>[<a href="#head">head</a>]</div>
<!-- <div>[<a href="#props">props</a>]</div> -->
<div>[<a href="#context">context</a>]</div> <div>[<a href="#context">context</a>]</div>
{% if report %} {% if report %}
<div>[<a href="#report">report</a>]</div> <div>[<a href="#report">report</a>]</div>
@ -21,7 +20,8 @@ Report: {{hint|abbreviate:150}} - {{id}} - Penpot Error Report (v4)
<div class="table-val"> <div class="table-val">
<h1><span class="not-important">Hint:</span> <br/> {{hint}}</h1> <h1><span class="not-important">Hint:</span> <br/> {{hint}}</h1>
<h2><span class="not-important">Reported at:</span> <br/> {{created-at}}</h2> <h2><span class="not-important">Reported at:</span> <br/> {{created-at}}</h2>
<h2><span class="not-important">Report ID:</span> <br/> {{id}}</h2> <h2><span class="not-important">Origin:</span> <br/> {{origin}}</h2>
<h2><span class="not-important">HREF:</span> <br/> {{href}}</h2>
</div> </div>
</div> </div>

View File

@ -117,7 +117,8 @@
{:context (-> (into (sorted-map) context) {:context (-> (into (sorted-map) context)
(pp/pprint-str :length 50)) (pp/pprint-str :length 50))
:props (pp/pprint-str props :length 50) :origin (::audit/name record)
:href (get props :href)
:hint (get props :hint) :hint (get props :hint)
:report (get props :report)})) :report (get props :report)}))

View File

@ -299,3 +299,8 @@
(js/console.log (format-throwable cause)) (js/console.log (format-throwable cause))
(finally (finally
(js/console.groupEnd)))))) (js/console.groupEnd))))))
(defn get-hint
[cause]
(or (some-> (ex-data cause) (get :hint) first-line)
(some-> (ex-message cause) first-line)))

View File

@ -72,7 +72,6 @@
(when-let [file-id (or (:file-id data) file-id)] (when-let [file-id (or (:file-id data) file-id)]
(println "File ID: " (str file-id))) (println "File ID: " (str file-id)))
(println "Version: " (:full cf/version)) (println "Version: " (:full cf/version))
(println "URI: " (str cf/public-uri))
(println "HREF: " (rt/get-current-href)) (println "HREF: " (rt/get-current-href))
(println) (println)
@ -88,24 +87,36 @@
(.error js/console "error on generating report" cause) (.error js/console "error on generating report" cause)
nil))) nil)))
(defn- show-not-blocking-error (defn submit-report
"Show a non user blocking error notification" "Report the error report to the audit log subsystem"
[cause] [& {:keys [event-name report hint] :or {event-name "unhandled-exception"}}]
(let [data (ex-data cause) (when (and (not (str/empty? hint))
hint (or (some-> (:hint data) ex/first-line) (string? report)
(ex-message cause))] (string? event-name))
(st/emit! (st/emit!
(ev/event {::ev/name "unhandled-exception" (ev/event {::ev/name event-name
:hint hint :hint hint
:href (rt/get-current-href) :href (rt/get-current-href)
:type (get data :type :unknown) :report report}))))
:report (generate-report cause)})
(ntf/show {:content (tr "errors.unexpected-exception" hint) (defn flash
:type :toast "Show error notification banner and emit error report"
:level :error [& {:keys [type hint cause] :or {type :handled}}]
:timeout 3000})))) (when (ex/exception? cause)
(when-let [event-name (case type
:handled "handled-exception"
:unhandled "unhandled-exception"
:silent nil)]
(let [report (generate-report cause)]
(submit-report :event-name event-name
:report report
:hint (ex/get-hint cause)))))
(st/emit!
(ntf/show {:content (or ^boolean hint (tr "errors.generic"))
:type :toast
:level :error
:timeout 5000})))
(defmethod ptk/handle-error :default (defmethod ptk/handle-error :default
[error] [error]
@ -114,7 +125,7 @@
(ptk/handle-error (assoc error :type :assertion)) (ptk/handle-error (assoc error :type :assertion))
(when-let [cause (::instance error)] (when-let [cause (::instance error)]
(ex/print-throwable cause :prefix "Unexpected Error") (ex/print-throwable cause :prefix "Unexpected Error")
(show-not-blocking-error cause)))) (flash :cause cause :type :unhandled))))
;; We receive a explicit authentication error; If the uri is for ;; We receive a explicit authentication error; If the uri is for
;; workspace, dashboard, viewer or settings, then assign the exception ;; workspace, dashboard, viewer or settings, then assign the exception
@ -203,7 +214,7 @@
(defmethod ptk/handle-error :assertion (defmethod ptk/handle-error :assertion
[error] [error]
(when-let [cause (::instance error)] (when-let [cause (::instance error)]
(show-not-blocking-error cause) (flash :cause cause :type :handled)
(ex/print-throwable cause :prefix "Assertion Error"))) (ex/print-throwable cause :prefix "Assertion Error")))
;; ;; All the errors that happens on worker are handled here. ;; ;; All the errors that happens on worker are handled here.
@ -307,7 +318,7 @@
:else :else
(when-let [cause (::instance error)] (when-let [cause (::instance error)]
(ex/print-throwable cause :prefix "Restriction Error") (ex/print-throwable cause :prefix "Restriction Error")
(show-not-blocking-error cause)))) (flash :cause cause :type :unhandled))))
;; This happens when the backed server fails to process the ;; This happens when the backed server fails to process the
;; request. This can be caused by an internal assertion or any other ;; request. This can be caused by an internal assertion or any other
@ -333,14 +344,14 @@
(set! last-exception cause) (set! last-exception cause)
(when-not (is-ignorable-exception? cause) (when-not (is-ignorable-exception? cause)
(ex/print-throwable cause :prefix "Uncaught Exception") (ex/print-throwable cause :prefix "Uncaught Exception")
(ts/schedule #(show-not-blocking-error cause))))) (ts/schedule #(flash :cause cause :type :unhandled)))))
(on-unhandled-rejection [event] (on-unhandled-rejection [event]
(.preventDefault ^js event) (.preventDefault ^js event)
(when-let [cause (unchecked-get event "reason")] (when-let [cause (unchecked-get event "reason")]
(set! last-exception cause) (set! last-exception cause)
(ex/print-throwable cause :prefix "Uncaught Rejection") (ex/print-throwable cause :prefix "Uncaught Rejection")
(ts/schedule #(show-not-blocking-error cause))))] (ts/schedule #(flash :cause cause :type :unhandled))))]
(.addEventListener g/window "error" on-unhandled-error) (.addEventListener g/window "error" on-unhandled-error)
(.addEventListener g/window "unhandledrejection" on-unhandled-rejection) (.addEventListener g/window "unhandledrejection" on-unhandled-rejection)

View File

@ -9,13 +9,12 @@
(:require (:require
["rxjs" :as rxjs] ["rxjs" :as rxjs]
[app.common.data :as d] [app.common.data :as d]
[app.common.exceptions :as ex]
[app.common.pprint :as pp] [app.common.pprint :as pp]
[app.common.uri :as u]
[app.common.uuid :as uuid] [app.common.uuid :as uuid]
[app.config :as cf] [app.config :as cf]
[app.main.data.auth :refer [is-authenticated?]] [app.main.data.auth :refer [is-authenticated?]]
[app.main.data.common :as dcm] [app.main.data.common :as dcm]
[app.main.data.event :as ev]
[app.main.errors :as errors] [app.main.errors :as errors]
[app.main.refs :as refs] [app.main.refs :as refs]
[app.main.repo :as rp] [app.main.repo :as rp]
@ -448,22 +447,22 @@
(mf/defc exception-section* (mf/defc exception-section*
{::mf/private true} {::mf/private true}
[{:keys [data route] :as props}] [{:keys [data] :as props}]
(let [type (get data :type) (let [type (get data :type)
report (mf/with-memo [data] cause (get data ::errors/instance)
(some-> data ::errors/instance errors/generate-report))
report (mf/with-memo [cause]
(when (ex/exception? cause)
(errors/generate-report cause)))
props (mf/spread-props props {:report report})] props (mf/spread-props props {:report report})]
(mf/with-effect [data route report] (mf/with-effect [report type cause]
(let [params (:query-params route) (when (and (ex/exception? cause)
params (u/map->query-string params)] (not (contains? #{:not-found :authentication} type)))
(st/emit! (ev/event {::ev/name "exception-page" (errors/submit-report :event-name "exception-page"
:type (get data :type :unknown) :report report
:href (rt/get-current-href) :hint (ex/get-hint cause))))
:hint (get data :hint)
:path (get route :path)
:report report
:params params}))))
(case type (case type
:not-found :not-found