Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also .

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also .
...
Checking mergeability… Don’t worry, you can still create the pull request.
  • 7 commits
  • 6 files changed
  • 0 commit comments
  • 1 contributor
View
19 README.md
@@ -7,6 +7,8 @@ For example, to print a nice stack trace in a REPL:
=> (use 'clj-stacktrace.repl)
=> ("foo")
java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn (NO_SOURCE_FILE:0)
+ => (pst)
+ java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn (NO_SOURCE_FILE:0)
Compiler.java:5440 clojure.lang.Compiler.eval
Compiler.java:5391 clojure.lang.Compiler.eval
core.clj:2382 clojure.core/eval
@@ -25,18 +27,23 @@ For example, to print a nice stack trace in a REPL:
NO_SOURCE_FILE:2 user/eval100
Compiler.java:5424 clojure.lang.Compiler.eval
-
In stack traces printed by `pst`:
-* Java methods are described with the usual `name.space.ClassName.methodName` convention and Clojure functions with their own `name.space/function-name` convention.
-* Anonymous clojure functions are denoted by adding an `[fn]` to their enclosing, named function.
+* Java methods are described with the usual
+ `name.space.ClassName.methodName` convention and Clojure functions
+ with their own `name.space/function-name` convention.
+* Anonymous clojure functions are denoted by adding an `[fn]` to their
+ enclosing, named function.
* "Caused by" cascades are shown as in regular java stack traces.
* Elements are vertically aligned for better readability.
* Printing is directed to `*out*`.
-If you want to direct the printing to somewhere other than `*out*`, either use `pst-on` to specify the output location or `pst-str` to capture the printing as a string.
+If you want to direct the printing to somewhere other than `*out*`,
+either use `pst-on` to specify the output location.
-The library also offers an API for programatically 'parsing' exceptions. This API is used internal for `pst` and can be used to e.g. improve development tools. Try for example:
+The library also offers an API for programatically 'parsing'
+exceptions. This API is used internal for `pst` and can be used to
+e.g. improve development tools. Try for example:
```clj
(use 'clj-stacktrace.core)
@@ -46,7 +53,7 @@ The library also offers an API for programatically 'parsing' exceptions. This AP
(parse-exception e)))
```
-If you use Leiningen, you can install clj-stacktrace on a per-user basis:
+If you use Leiningen, you can install clj-stacktrace on a user-level basis:
$ lein plugin install clj-stacktrace 0.2.4
View
4 src/clj_stacktrace/core.clj
@@ -76,7 +76,7 @@
:method (.getMethodName elem)))))
(defn parse-trace-elems
- "Returns a seq of maps providing usefull information about the java stack
+ "Returns a seq of maps providing useful information about the java stack
trace elements. See parse-trace-elem."
[elems]
(map parse-trace-elem elems))
@@ -110,7 +110,7 @@
base)))
(defn parse-exception
- "Returns a Clojure map providing usefull informaiton about the exception.
+ "Returns a Clojure map providing useful information about the exception.
The map has keys
:class Class of the exception.
:message Regular exception message string.
View
41 src/clj_stacktrace/repl.clj
@@ -1,6 +1,6 @@
(ns clj-stacktrace.repl
- (:use clj-stacktrace.core)
- (:require [clj-stacktrace.utils :as utils]))
+ (:use [clj-stacktrace.core :only [parse-exception]]
+ [clj-stacktrace.utils :only [omit-frames fence rjust]]))
(def color-codes
{:red "\033[31m"
@@ -59,16 +59,14 @@
(defn pst-elem-str
[color? parsed-elem print-width]
(colored color? (elem-color parsed-elem)
- (str (utils/rjust print-width (source-str parsed-elem))
+ (str (rjust print-width (source-str parsed-elem))
" " (method-str parsed-elem))))
(defn pst-elems-on
[^java.io.Writer on color? parsed-elems & [source-width]]
(let [print-width (+ 6 (or source-width
- (utils/fence
- (sort
- (map #(.length ^String %)
- (map source-str parsed-elems))))))]
+ (fence (sort (for [elem parsed-elems]
+ (count (source-str elem)))))))]
(doseq [parsed-elem parsed-elems]
(.append on ^String (pst-elem-str color? parsed-elem print-width))
(.append on "\n")
@@ -80,11 +78,12 @@
(.flush on))
(defn- pst-cause-on
- [^java.io.Writer on color? exec source-width]
+ [^java.io.Writer on exec {:keys [source-width omit color?]}]
(pst-caused-by-on on color?)
(pst-class-on on color? (:class exec))
(pst-message-on on color? (:message exec))
- (pst-elems-on on color? (:trimmed-elems exec) source-width)
+ (pst-elems-on on color? (omit-frames (:trimmed-elems exec) omit)
+ source-width)
(if-let [cause (:cause exec)]
(pst-cause-on on color? cause source-width)))
@@ -94,29 +93,33 @@
[excp]
(let [this-source-width (->> (:trace-elems excp)
(map (comp count source-str))
- (sort)
- (utils/fence))]
+ (sort) (fence))]
(if-let [cause (:cause excp)]
(max this-source-width (find-source-width cause))
this-source-width)))
-(defn pst-on [on color? e]
+(defn pst-on
"Prints to the given Writer on a pretty stack trace for the given exception e,
ANSI colored if color? is true."
+ [on e {:keys [omit color?] :as opts}]
(let [exec (parse-exception e)
- source-width (find-source-width exec)]
+ source-width (find-source-width exec)
+ color? (or color? (:color? opts) (:test-color opts))]
(pst-class-on on color? (:class exec))
(pst-message-on on color? (:message exec))
- (pst-elems-on on color? (:trace-elems exec) source-width)
+ (pst-elems-on on color? (omit-frames (:trace-elems exec) omit) source-width)
(if-let [cause (:cause exec)]
- (pst-cause-on on color? cause source-width))))
+ (pst-cause-on on cause
+ (assoc opts
+ :source-width source-width
+ :color? color?)))))
(defn pst
"Print to *out* a pretty stack trace for an exception, by default *e."
- [& [e]]
- (pst-on *out* false (or e *e)))
+ [& [e & {:as opts}]]
+ (pst-on *out* (or e *e) opts))
(defn pst+
"Like pst, but with ANSI terminal color coding."
- [& [e]]
- (pst-on *out* true (or e *e)))
+ [& [e & {:as opts}]]
+ (pst-on *out* (or e *e) (assoc opts :color? true)))
View
16 src/clj_stacktrace/utils.clj
@@ -37,3 +37,19 @@
q3 (quartile3 coll)
iqr (- q3 q1)]
(int (+ q3 (/ (* 3 iqr) 2)))))
+
+(defn- omitter-fn [to-omit]
+ (if (instance? java.util.regex.Pattern to-omit)
+ ;; Curse you, non ifn regexes!
+ (comp (partial re-find to-omit) pr-str)
+ to-omit))
+
+(defn omit-frames
+ "Remove frames matching to-omit, which can be a function or regex."
+ [trace-elems to-omit]
+ (if-let [omit? (omitter-fn to-omit)]
+ (reduce (fn [trace-elems elem]
+ (if (omit? elem)
+ trace-elems
+ (conj trace-elems elem))) [] trace-elems)
+ trace-elems))
View
11 src/leiningen/hooks/clj_stacktrace_test.clj
@@ -3,12 +3,11 @@
[robert.hooke :only [add-hook]]))
(defn- hook-form [form project]
- (let [pst (if (:test-color (:clj-stacktrace project))
- 'clj-stacktrace.repl/pst+
- 'clj-stacktrace.repl/pst)]
- `(do (alter-var-root (resolve '~'clojure.stacktrace/print-cause-trace)
- (constantly @(resolve '~pst)))
- ~form)))
+ `(do (alter-var-root (resolve '~'clojure.stacktrace/print-cause-trace)
+ (constantly (fn [e#]
+ (@(resolve '~'pst) e#
+ ~(:clj-stacktrace project)))))
+ ~form))
(defn- add-stacktrace-hook [eval-in-project project form & [h s init]]
(eval-in-project project (hook-form form project)
View
20 test/clj_stacktrace/repl_test.clj
@@ -1,7 +1,6 @@
(ns clj-stacktrace.repl-test
- (:use clojure.test)
- (:use clj-stacktrace.utils)
- (:use clj-stacktrace.repl))
+ (:use [clojure.test]
+ [clj-stacktrace.repl]))
(defmacro with-cascading-exception
"Execute body in the context of a variable bound to an exception instance
@@ -18,14 +17,17 @@
(binding [*e e]
(is (with-out-str (pst))))))
-(deftest test-pst-str
- (with-cascading-exception e
- (is (pst-str e))
- (binding [*e e]
- (is (pst-str)))))
-
(deftest test-pst+
(with-cascading-exception e
(is (with-out-str (pst+ e)))
(binding [*e e]
(is (with-out-str (pst+))))))
+
+(deftest test-omit
+ (with-cascading-exception e
+ (is (not (re-find #"repl-test" (with-out-str
+ (pst e :omit #"repl-test")))))
+ (is (not (re-find #"Compiler.java"
+ (with-out-str
+ (pst e :omit (fn [e]
+ (= "Compiler.java" (:file e))))))))))

No commit comments for this range