The new clj-commons.pretty.annotations
namespace provides functions to help create pretty errors
when parsing or interpretting text:
SELECT DATE, AMT FROM PAYMENTS WHEN AMT > 10000
▲▲▲ ▲▲▲▲
│ │
│ └╴ Unknown token
│
└╴ Invalid column name
Here, the errors (called "annotations") are presented as callouts targetting specific portions of the input line.
The callouts
function can handle multiple annotations on a single line, with precise control over styling and layout.
The annotate-lines
function builds on callouts
to produce output of multiple lines from some source,
interspersed with callouts:
1: SELECT DATE, AMT
▲▲▲
│
└╴ Invalid column name
2: FROM PAYMENTS WHEN AMT > 10000
▲▲▲▲
│
└╴ Unknown token
The new clj-commons.pretty.spec
namespace provides type and function specs for the clj-commons.ansi
and
clj-commons.pretty.annotations
namespaces.
Added clj-commons.ansi/pout
to replace the pcompose
function; they are identical, but the pout
name makes more
sense, given that perr
exists.
Changed how clj-commons.ansi/compose
creates ANSI SGR strings; this works around an issue in many terminal emulators
where changing boldness from faint to normal, or faint to bold, is not implemented correctly. compose
now resets fonts
before each font change, which allows such transitions to render correctly.
Added clj-commons.format.exceptions/default-frame-rules
to supply defaults for *default-frame-rules*
which makes it much easier to override the default rules.
Added function clj-commons.format.exceptions/format-stack-trace-element
which can be used to convert a Java
StackTraceElement into a demangled, readable string, using the same logic as format-exception.
In a Clojure stack frame, repeated elements may be abbreviated; for example,
what was output in 3.0.0 as
integration.diplomat.components.github-api-test/fn/fn/fn/fn/fn/fn/fn/fn/fn/fn/fn/fn/fn/fn
will be output in 3.1.0 as integration.diplomat.components.github-api-test/fn{x14}
(this is an actual test case!)
These crazily nested functions occur when using macro-intensive libraries such as
nubank/state-flow and funcool/cats.
BREAKING CHANGES:
Moved the io.aviso/pretty compatibility layer (introduced in 2.5.0) to new library org.clj-commons/pretty-aviso-bridge.
Other changes:
clj-commons.format.exceptions
compose
can now be a vector of individual terms, rather than a single keyword; e.g. [:bold :red]
as an alternative to :bold.red
. This can be useful when the font is computed, rather than a static literal.Minor bug fixes.
BREAKING CHANGES
clojure.core/apply
is now omitted (in formatted stack traces)Other changes:
A limited number of vars and functions defined by the io.aviso/pretty artifact have been added, allowing org.clj-commons/pretty to swap in for io.aviso/pretty in many cases.
BREAKING CHANGES
clj-commons.format.table/print-table
now centers title columns by default,
and adds a :title-pad key to the column map to control this explicitly.Other changes:
compose
now supports a new value for :pad; the value :both is used to
center the content, adding spaces on both sides.
A new function, clj-commons.ansi/perr
, composes its inputs and prints
them to *err*
, a common behavior for command line tools.
A new namespace, clj-commons.format.table
, is used to format tabular output; a
prettier version of clojure.pprint/print-table
This release contains only minor bug fixes:
This release is bug fixes and minor improvements.
The new clj-commons.ansi.pcompose
function is used to compose an ANSI formatted string and then print it,
an exceptionally common case.
The prior restriction with compose
, that spans nested within spans with a width could not also have a width,
has been removed.
Bug fixes
install-pretty-exceptions
has been changed to now extend
clojure.core/print-method
for Throwable, using format-exception
.
Exceptions printed by the REPL are now formatted using Pretty;
further, when using clojure.test
, when a thrown-with-msg?
assertion fails,
the actual exception is now formatted (as this also, indirectly, uses print-method
).
Bug Fixes
Bug Fixes
This release moves the library to clj-commons, and changes the root namespace from
io.aviso
to clj-commons
. It strips down the library to its essentials, removing
the columns
, component
, and logging
namespaces entirely.
ansi
namespace to primarily expose the compose
function and not dozens of constants and functionsansi
determines whether to enable or disable ANSI codes at execution timeansi
now honors the NO_COLOR
environment variablerepl
namespaceexceptions
namespace, including changes to the *fonts*
varlogging
namespace and dependency on org.clojure/tools.logging
component
namespace, but the example is still present in the documentationwrite-exception
was renamed to print-exception
write-binary
and write-binary-delta
renamed to print-binary
and print-binary-delta
compose
can now pad a span of text with spaces (on the left or right) to a desired widthcompose
The compose
function would collapse blank strings to empty strings.
io.aviso.ansi
: Add support for faint
, underlined
, and not-underlined
text, and improvements
to docstrings.
A new function, io.aviso.ansi/compose
uses a Hiccup-inspired
syntax to make composing text with ANSI fonts (foreground and background colors, inverse, bold, and
italic) easy and concise.
The override to enable or disable ANSI text has been amended: the first check is for
a JVM system property, io.aviso.ansi.enable
, then if that is not set, the ENABLE_ANSI_COLORS
environment variable.
The default stack frame filter now terminates at any speclj.*
namespace.
The io.aviso.ansi
namespace now determines whether output is connected to a terminal,
and disables fonts and colors if so; this can be overridden with the ENABLE_ANSI_COLORS
environment variable.
Added a -main
function to io.aviso.repl
; this installs pretty exceptions before delegating
to clojure.main/main
. Thus, clojure -m io.aviso.repl -m org.example.myapp
will ultimately
pass any remaining command line arguments to org.example.myapp/-main
.
The pretty replacement for clojure.repl/pst
now writes to *err*
, not *out*
.
Output from write-exception
is now buffered; this should reduce the
interleaving of exception output when multiple threads are writing
exceptions simultaneously.
Prevent warnings when using with Clojure 1.11.
Restore compatibility with Clojure 1.7.0.
BinaryData protocol extended onto java.nio.ByteBuffer.
Incompatible Changes:
Removed the io.aviso.writer
namespace and changed many functions
to simply write to *out*
rather than take a writer parameter.
It is now necessary to setup explicit :middleware in your project.clj
, as
Leiningen is phasing out implicit middleware.
See the manual for more details.
Support Clojure 1.10.
Add support for highlighting application frames using io.aviso.exception/*app-frame-names*
.
When printing sorted maps, the keys are presented in map order (not sorted).
The new namespace, io.aviso.component
, can be used to produce concise output
for systems and components that are pretty printed as part of exception output.
Added possibility to disable default ANSI fonts by setting an environment variable DISABLE_DEFAULT_PRETTY_FONTS
to any value.
New functions in io.aviso.repl
for copying text from the clipboard,
and pretty printing it as EDN or as a formatted exception.
Switch to using macros instead of eval to play nicer with AOT
Support all arities of clojure.repl/pst
Fix bad ns declaration and reflection warnings
Fix an issue where the code injected by the plugin could get damaged by other plugins, resulting in a ClassNotFoundException.
A warning is now produced when using pretty as a plugin, but it is not a project dependency.
Qualified keys in exception maps are now printed properly.
To get around Clojure 1.8 deep linking, io.aviso.repl/install-pretty-exceptions
now reloads clojure.test
after overriding other functions (such as clojure.stacktrace/print-stack-trace
).
The writer used in write-exception is now locked and flush on newline is disabled; this helps ensure that multiple threads do not write their output interspersed in an unreadable way.
Internal change to how exception properties are pretty-printed.
parse-exception
can now handle method names containing <
and >
(used for instance and class
constructor methods), as well as other cases from real-life stack traces.
Stack traces were omitted when the root exception was via ex-info
; this has been corrected.
Fixed a bug where parse-exception
would fail if the source was "Unknown Source" instead
of a file name and line number.
Improved docstrings for ANSI font constants and functions.
Added support for invokePrim() stack frames. These are hidden as with Clojure 1.8 invokeStatic() frames.
Stack frames that represent REPL input now appear as REPL Input
in the file column, rather than
something like form-init9201216130440431126.clj
.
Source files with extension .cljc
(introduced in Clojure 1.7) are now recognized as Clojure code.
It is now possible to parse a block of exception text (say, copied from an output log) so that it may be formatted. Because of the wide range in which different JDKs may output exceptions, this is considered experimental.
Incompatible change: write-binary now expects an optional map (not a varargs of keys and values) for options such as :ascii and :line-bytes.
Pretty will identify repeating stack frames (for example, from an infinite loop) and only print the stack frame once, but append the number of times it repeats.
Made an adjustment for Clojure 1.8's new direct linking feature.
Improved the way Pretty acts as a Leiningen plugin. Pretty exceptions reports are now produced for both REPL sessions and test executions.
The io.aviso.nrepl namespace has been removed.
Print a blank line before the exception output, when reporting a clojure.test exception. Previously, the first line was was on the same line as the "actual:" label, which interfered with columnar output.
The built in stack frame filtering rules are now better documented, and speclj.* is now included as :terminate.
You may now add pretty to your Leiningen :plugins list; it will automatically add the Pretty nREPL middleware.
io.aviso.repl/install-pretty-logging now installs a default Thread uncaughtExceptionHandler.
There's a new arity of io.aviso.columns/write-rows that streamlines the whole process (it can calculate column widths automatically).
The Clojure ExceptionInfo exception is now treated specially.
Changed io.aviso.logging to always use the current value of *default-logging-filter* rather than capturing its value when install-pretty-logging is invoked.
Sometimes, the file name of a stack trace element is a complete path (this occurs with some testing frameworks); in that case, Pretty will now strip off the prefix from the path, when it matches the current directory path. This keeps the file name column as narrow as possible.
io.aviso.exception/*default-frame-filter* has been added, and acts as the default frame filter for write-exception (previously there was no default).
Starting in this release, the exception report layout has changed significantly; however, the old behavior is still available via the io.aviso.exceptions/*traditional* dynamic var.
A new namespace, io.aviso.logging, includes code to setup clojure.tools.logging to make use of pretty exception output.
It is now possible to control how particular types are formatted when printing the properties of an exception. This can be very useful when using (for example) Stuart Sierra's component library.
The default stack-frame filter now excludes frames from the sun.reflect
package (and sub-packages).
For exceptions added via io.aviso.repl/install-pretty-exceptions
, the filtering omits frames from the clojure.lang
package, and terminates output when the frames for the REPL are reached.
It is now possible to specify a filter for stack frames in the exception output. Frames can be hidden (not displayed at all), or omitted (replaced with '...').
This can remove significant clutter from the exception output, making it that much easier to identify the true cause of the exception.
Can you improve this documentation? These fine people already did:
Howard M. Lewis Ship, Howard Lewis Ship, Paudi Moriarty & Piotr BzdylEdit on GitHub
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close