Skip to content

Commit

Permalink
Merge pull request #50 from timothypratley/getnextexception
Browse files Browse the repository at this point in the history
adds support for SQLException getNextException #39
  • Loading branch information
magnars authored May 18, 2018
2 parents 2dc7b56 + c8b841a commit 96772fc
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 56 deletions.
68 changes: 44 additions & 24 deletions dev/prone/demo.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
(:require [clojure.java.io :as io]
[datomic.api :as d]
[prone.debug :refer [debug]]
[prone.middleware :refer [wrap-exceptions]])
(:import [java.io ByteArrayInputStream]))
[prone.middleware :refer [wrap-exceptions]]
[hiccup.core :as h])
(:import [java.io ByteArrayInputStream]
(java.sql SQLException)))

(defrecord MyRecord [num])

Expand Down Expand Up @@ -57,13 +59,6 @@

(defn handler [req]
(cond

;; serve source maps
(re-find #"prone.js.map$" (:uri req))
{:status 200
:headers {"Content-Type" "application/octet-stream"}
:body (slurp (io/resource "prone/generated/prone.js.map"))}

;; throw exception in dependency (outside of app)
(= (:uri req) "/external-throw") (re-find #"." nil)

Expand All @@ -82,6 +77,15 @@
(= (:uri req) "/caused-by")
(throw (Exception. "It went wrong because of something else" (create-intermediate-cause)))

;; throw an SQLException with a cause
(= (:uri req) "/sql")
(throw (doto (SQLException. "Has a next exception")
(.initCause (create-intermediate-cause))
(.setNextException
(doto (SQLException. "Next exception!")
(.setNextException (SQLException. "Next next exception!!"))))))


;; use the debug function to halt rendering (and inspect data)
(= (:uri req) "/debug")
(do
Expand All @@ -96,21 +100,37 @@
:body "<h1>Hello, bittersweet and slightly tangy world</h1>"})

;; basic case
:else (do
;; A map with nil as key, that is too big to render inline
;; (Used to cause a bug in the MapBrowser)
(debug {nil [1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10]})
(debug "What's this" {:id 42 :req req})
(throw (Exception. "Oh noes!")))))
(= (:uri req) "/basic")
(do
;; A map with nil as key, that is too big to render inline
;; (Used to cause a bug in the MapBrowser)
(debug {nil [1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10]})
(debug "What's this" {:id 42 :req req})
(throw (Exception. "Oh noes!")))

;; serve source maps
(re-find #"prone.js.map$" (:uri req))
{:status 200
:headers {"Content-Type" "application/octet-stream"}
:body (slurp (io/resource "prone/generated/prone.js.map"))}

:else
{:status 200
:headers {"content-type" "text/html"}
:body (h/html
[:h2 "Examples:"]
(into [:ul]
(for [x ["external-throw" "ex-info" "lazy" "caused-by" "sql" "debug" "basic"]]
[:li [:a {:href x} x]])))}))

(def app
(-> handler
Expand Down
23 changes: 14 additions & 9 deletions src/prone/prep.clj
Original file line number Diff line number Diff line change
Expand Up @@ -116,16 +116,21 @@
[idx frame]
(assoc frame :id idx))

(defn maybe-update [m k f & args]
(if (contains? m k)
(apply update m k f args)
m))

(defn- prep-error [error app-namespaces]
(-> (if (:caused-by error)
(update-in error [:caused-by] #(prep-error % app-namespaces))
error)
(update-in [:frames]
#(->> %
(map-indexed set-frame-id)
(map (partial set-application-frame app-namespaces))
(mapv add-source)))
(update-in [:data] (comp prepare-for-serialization realize/realize))
(-> error
(maybe-update :caused-by prep-error app-namespaces)
(maybe-update :next prep-error app-namespaces)
(update :frames
#(->> %
(map-indexed set-frame-id)
(map (partial set-application-frame app-namespaces))
(mapv add-source)))
(update :data (comp prepare-for-serialization realize/realize))
add-browsable-data))

(defn- add-browsable-debug
Expand Down
10 changes: 9 additions & 1 deletion src/prone/stacks.clj
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
(ns prone.stacks
"Extract data from stack traces and represent them with plain maps"
(:require [clojure.java.io :as io]
[clojure.string :as str]))
[clojure.string :as str])
(:import (java.sql SQLException)))

(defn- find-loaded-from [url]
(when-let [path (and (io/resource url)
Expand Down Expand Up @@ -89,6 +90,12 @@
(assoc normalized :caused-by (normalize-exception cause))
normalized))

(defn- add-next [normalized exception]
(if-let [n (when (instance? SQLException exception)
(.getNextException exception))]
(assoc normalized :next (normalize-exception n))
normalized))

(defn- add-frame-from-message [ex]
(if-let [data (and (:message ex)
(re-find #"\(([^(]+.cljc?):(\d+):(\d+)\)" (:message ex)))]
Expand Down Expand Up @@ -118,4 +125,5 @@
:frames (->> exception .getStackTrace (map normalize-frame))}
(add-data exception)
(add-cause exception)
(add-next exception)
(add-frame-from-message))))
58 changes: 36 additions & 22 deletions src/prone/ui/components/app.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,47 @@
[prone.ui.components.code-excerpt :refer [CodeExcerpt]]
[prone.ui.utils :refer [action]]
[quiescent.core :as q :include-macros true]
[quiescent.dom :as d]))
[quiescent.dom :as d]
[clojure.string :as str]))

(defn chain-type-name [k]
(str/capitalize (str/replace-all (name k) #"-" " ")))

(defn exception-chain [chain-type error chans]
(when-let [child (get error chain-type)]
(d/span {}
(str " " (chain-type-name chain-type) " ")
(d/a {:href "#"
:onClick (action #(put! (:navigate-data chans)
[:error [:concat [chain-type]]]))}
(:type child)))))

(defn chain-back-nav [paths chans]
(if (seq (:other-error paths))
(d/a {:href "#"
:onClick (action #(put! (:navigate-data chans)
[:other-error [:reset nil]]))}
"< back")
(when (seq (:error paths))
(d/a {:href "#"
:onClick (action #(put! (:navigate-data chans)
[:error [:reset (butlast (:error paths))]]))}
"< back"))))

(q/defcomponent ErrorHeader
[{:keys [error location paths]} chans]
(d/header {:className "exception"}
(d/h2 {}
(d/strong {} (:type error))
(d/span {} " at " location)
(when (or (:caused-by error)
(seq (:error paths))
(:other-error paths))
(d/span {:className "caused-by"}
(if (seq (:other-error paths))
(d/a {:href "#"
:onClick (action #(put! (:navigate-data chans)
[:other-error [:reset nil]]))}
"< back")
(when (seq (:error paths))
(d/a {:href "#"
:onClick (action #(put! (:navigate-data chans)
[:error [:reset (butlast (:error paths))]]))}
"< back")))
(when-let [caused-by (:caused-by error)]
(d/span {} " Caused by " (d/a {:href "#"
:onClick (action #(put! (:navigate-data chans)
[:error [:concat [:caused-by]]]))}
(:type caused-by)))))))
(d/strong {} (:type error))
(d/span {} " at " location)
(when (or (get error :caused-by)
(get error :next)
(seq (:error paths))
(:other-error paths))
(d/span {:className "caused-by"}
(chain-back-nav paths chans)
(exception-chain :caused-by error chans)
(exception-chain :next error chans))))
(d/p {} (or (:message error)
(d/span {} (:class-name error)
(d/span {:className "subtle"} " [no message]"))))))
Expand Down

0 comments on commit 96772fc

Please sign in to comment.