mirror of
https://github.com/penpot/penpot.git
synced 2025-02-10 00:58:26 -05:00
✨ Improve error reporting.
This commit is contained in:
parent
d24d45f4cb
commit
9f0e156916
7 changed files with 107 additions and 144 deletions
|
@ -13,15 +13,40 @@
|
|||
}
|
||||
pre {
|
||||
margin: 0px;
|
||||
line-height: 17px;
|
||||
}
|
||||
|
||||
main {
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
nav {
|
||||
position: fixed;
|
||||
width: 100vw;
|
||||
top: 0;
|
||||
left: 0;
|
||||
padding: 5px 20px;
|
||||
display: flex;
|
||||
background: #e3e3e3;
|
||||
}
|
||||
|
||||
nav > div {
|
||||
text-transform: uppercase;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
nav > div:not(:last-child) {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
* {
|
||||
font-family: "JetBrains Mono", monospace;
|
||||
font-size: 12px;
|
||||
}
|
||||
.table {
|
||||
margin-top: 40px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.table-row {
|
||||
|
@ -34,6 +59,9 @@
|
|||
font-weight: 600;
|
||||
width: 60px;
|
||||
padding: 4px;
|
||||
|
||||
padding-top: 40px;
|
||||
margin-top: -40px;
|
||||
}
|
||||
|
||||
.table-val {
|
||||
|
@ -57,147 +85,68 @@
|
|||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="table">
|
||||
<div class="table-row">
|
||||
<div class="table-key" title="Error ID">ERID: </div>
|
||||
<div class="table-val">{{id}}</div>
|
||||
</div>
|
||||
{% if profile-id %}
|
||||
<div class="table-row">
|
||||
<div class="table-key" title="Profile ID">PFID: </div>
|
||||
<div class="table-val">{{profile-id}}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if user-agent %}
|
||||
<div class="table-row">
|
||||
<div class="table-key">UAGT: </div>
|
||||
<div class="table-val">{{user-agent}}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if frontend-version %}
|
||||
<div class="table-row">
|
||||
<div class="table-key">FVER: </div>
|
||||
<div class="table-val">{{frontend-version}}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="table-row">
|
||||
<div class="table-key">BVER: </div>
|
||||
<div class="table-val">{{version}}</div>
|
||||
</div>
|
||||
|
||||
{% if host %}
|
||||
<div class="table-row">
|
||||
<div class="table-key">HOST: </div>
|
||||
<div class="table-val">{{host}}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if tenant %}
|
||||
<div class="table-row">
|
||||
<div class="table-key">ENV: </div>
|
||||
<div class="table-val">{{tenant}}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if public-uri %}
|
||||
<div class="table-row">
|
||||
<div class="table-key">PURI: </div>
|
||||
<div class="table-val">{{public-uri}}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if type %}
|
||||
<div class="table-row">
|
||||
<div class="table-key">TYPE: </div>
|
||||
<div class="table-val">{{type}}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if code %}
|
||||
<div class="table-row">
|
||||
<div class="table-key">CODE: </div>
|
||||
<div class="table-val">{{code}}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if error %}
|
||||
<div class="table-row">
|
||||
<div class="table-key">CLSS: </div>
|
||||
<div class="table-val">{{error.class}}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if hint %}
|
||||
<div class="table-row">
|
||||
<div class="table-key">HINT: </div>
|
||||
<div class="table-val">{{hint}}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if method %}
|
||||
<div class="table-row">
|
||||
<div class="table-key">PATH: </div>
|
||||
<div class="table-val">{{method|upper}} {{path}}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div>(<a href="#explain">go to explain</a>)</div>
|
||||
<div>(<a href="#edata">go to edata</a>)</div>
|
||||
<div>(<a href="#trace">go to trace</a>)</div>
|
||||
|
||||
{% if params %}
|
||||
<div id="params" class="table-row multiline">
|
||||
<div class="table-key">PARAMS: </div>
|
||||
<div class="table-val">
|
||||
<pre>{{params}}</pre>
|
||||
</div>
|
||||
</div>
|
||||
<nav>
|
||||
<div>[<a href="#context">context</a>]</div>
|
||||
<div>[<a href="#params">params</a>]</div>
|
||||
{% if spec-problems %}
|
||||
<div>[<a href="#edata">spec</a>]</div>
|
||||
{% endif %}
|
||||
|
||||
{% if data %}
|
||||
<div id="edata" class="table-row multiline">
|
||||
<div class="table-key">ERROR DATA: </div>
|
||||
<div class="table-val">
|
||||
<pre>{{data}}</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div>[<a href="#edata">data</a>]</div>
|
||||
{% endif %}
|
||||
{% if trace %}
|
||||
<div>[<a href="#trace">trace</a>]</div>
|
||||
{% endif %}
|
||||
</nav>
|
||||
<main>
|
||||
<div class="table">
|
||||
<div class="table-row multiline">
|
||||
<div id="context" class="table-key">CONTEXT: </div>
|
||||
<div class="table-val">
|
||||
<pre>{{context}}</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if spec-problems %}
|
||||
<div id="edata" class="table-row multiline">
|
||||
<div class="table-key">SPEC PROBLEMS: </div>
|
||||
<div class="table-val">
|
||||
<pre>{{spec-problems}}</pre>
|
||||
{% if params %}
|
||||
<div class="table-row multiline">
|
||||
<div id="params" class="table-key">PARAMS: </div>
|
||||
<div class="table-val">
|
||||
<pre>{{params}}</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if cause %}
|
||||
<div id="trace" class="table-row multiline">
|
||||
<div class="table-key">TRACE:</div>
|
||||
<div class="table-val">
|
||||
<pre>{{cause}}</pre>
|
||||
<!-- NOTE: this is legacy, for old error data saved on the database -->
|
||||
{% if data %}
|
||||
<div class="table-row multiline">
|
||||
<div id="edata" class="table-key">ERROR DATA: </div>
|
||||
<div class="table-val">
|
||||
<pre>{{data}}</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% elif trace %}
|
||||
<div id="trace" class="table-row multiline">
|
||||
<div class="table-key">TRACE:</div>
|
||||
<div class="table-val">
|
||||
<pre>{{trace}}</pre>
|
||||
{% endif %}
|
||||
|
||||
{% if spec-problems %}
|
||||
<div class="table-row multiline">
|
||||
<div id="spec-problems" class="table-key">SPEC PROBLEMS: </div>
|
||||
<div class="table-val">
|
||||
<pre>{{spec-problems}}</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% elif error %}
|
||||
<div id="trace" class="table-row multiline">
|
||||
<div class="table-key">TRACE:</div>
|
||||
<div class="table-val">
|
||||
<pre>{{error.trace}}</pre>
|
||||
{% endif %}
|
||||
|
||||
{% if trace %}
|
||||
<div class="table-row multiline">
|
||||
<div id="trace" class="table-key">TRACE:</div>
|
||||
<div class="table-val">
|
||||
<pre>{{trace}}</pre>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
[app.common.spec :as us]
|
||||
[app.common.transit :as t]
|
||||
[app.common.uuid :as uuid]
|
||||
[clojure.pprint :as ppr]
|
||||
[app.config :as cf]
|
||||
[app.db :as db]
|
||||
[app.util.template :as tmpl]
|
||||
|
@ -99,7 +100,6 @@
|
|||
(ex/raise :type :validation :code :invalid-arguments))))
|
||||
|
||||
|
||||
|
||||
(defn retrieve-error
|
||||
[{:keys [pool]} request]
|
||||
(letfn [(parse-id [request]
|
||||
|
@ -107,14 +107,23 @@
|
|||
id (us/uuid-conformer id)]
|
||||
(when (uuid? id)
|
||||
id)))
|
||||
|
||||
(retrieve-report [id]
|
||||
(ex/ignoring
|
||||
(when-let [{:keys [content] :as row} (db/get-by-id pool :server-error-report id)]
|
||||
(assoc row :content (db/decode-transit-pgobject content)))))
|
||||
(some-> (db/get-by-id pool :server-error-report id) :content db/decode-transit-pgobject)))
|
||||
|
||||
(render-template [{:keys [content] :as report}]
|
||||
(some-> (io/resource "error-report.tmpl")
|
||||
(tmpl/render content)))]
|
||||
(render-template [report]
|
||||
(binding [ppr/*print-right-margin* 300]
|
||||
(let [context (dissoc report :trace :cause :params :data :spec-prob :spec-problems)
|
||||
params {:context (with-out-str (ppr/pprint context))
|
||||
:data (:data report)
|
||||
:trace (or (:cause report)
|
||||
(:trace report)
|
||||
(some-> report :error :trace))
|
||||
:params (:params report)}]
|
||||
(-> (io/resource "error-report.tmpl")
|
||||
(tmpl/render params)))))
|
||||
]
|
||||
|
||||
(when-not (authorized? pool request)
|
||||
(ex/raise :type :authentication
|
||||
|
|
|
@ -30,14 +30,13 @@
|
|||
:hint (or (:hint data) (ex-message error))
|
||||
:params (l/stringify-data (:params request))
|
||||
:spec-problems (some-> data ::s/problems)
|
||||
:data (some-> data (dissoc ::s/problems))
|
||||
:ip-addr (parse-client-ip request)
|
||||
:profile-id (:profile-id request)}
|
||||
|
||||
(let [headers (:headers request)]
|
||||
{:user-agent (get headers "user-agent")
|
||||
:frontend-version (get headers "x-frontend-version" "unknown")})
|
||||
|
||||
(dissoc data ::s/problems))))
|
||||
:frontend-version (get headers "x-frontend-version" "unknown")}))))
|
||||
|
||||
(defmulti handle-exception
|
||||
(fn [err & _rest]
|
||||
|
@ -56,8 +55,7 @@
|
|||
(defmethod handle-exception :validation
|
||||
[err _]
|
||||
(let [edata (ex-data err)]
|
||||
{:status 400
|
||||
:body (dissoc edata ::s/problems)}))
|
||||
{:status 400 :body edata}))
|
||||
|
||||
(defmethod handle-exception :assertion
|
||||
[error request]
|
||||
|
|
|
@ -73,6 +73,7 @@
|
|||
(if-let [{:keys [id profile-id] :as session} (retrieve-from-request cfg request)]
|
||||
(do
|
||||
(a/>!! (::events-ch cfg) id)
|
||||
(l/set-context! {:profile-id profile-id})
|
||||
(handler (assoc request :profile-id profile-id)))
|
||||
(handler request))))
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@
|
|||
(let [event (parse-event event)
|
||||
uri (cf/get :public-uri)]
|
||||
(l/debug :hint "registering error on database" :id (:id event)
|
||||
:uri (str uri "/dbg/error-by-id/" (:id event)))
|
||||
:uri (str uri "/dbg/error/" (:id event)))
|
||||
(persist-on-database! cfg event))
|
||||
(catch Exception e
|
||||
(l/warn :hint "unexpected exception on database error logger"
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
val
|
||||
|
||||
(coll? val)
|
||||
(binding [clojure.pprint/*print-right-margin* 120]
|
||||
(binding [clojure.pprint/*print-right-margin* 200]
|
||||
(-> (with-out-str (pprint val))
|
||||
(simple-prune (* 1024 1024 3))))
|
||||
|
||||
|
@ -83,6 +83,12 @@
|
|||
(stringify-data val)])))
|
||||
data)))
|
||||
|
||||
#?(:clj
|
||||
(defn set-context!
|
||||
[data]
|
||||
(ThreadContext/putAll (data->context-map data))
|
||||
nil))
|
||||
|
||||
#?(:clj
|
||||
(defmacro with-context
|
||||
[data & body]
|
||||
|
|
|
@ -256,7 +256,7 @@
|
|||
(let [data (s/explain-data spec data)]
|
||||
(throw (ex/error :type :validation
|
||||
:code :spec-validation
|
||||
:data data))))
|
||||
::s/problems (::s/problems data)))))
|
||||
result))
|
||||
|
||||
(defmacro instrument!
|
||||
|
|
Loading…
Add table
Reference in a new issue