Structured markup for throw
and trace
messages that make Nix more robust
#7795
Labels
error-messages
Confusing messages and better diagnostics
feature
Feature request or proposal
language
The Nix expression language; parser, interpreter, primops, evaluation, etc
Is your feature request related to a problem? Please describe.
Nix diagnostic output has been getting much nicer. Let's continue the trend and make "user space" output nice too.
Error messages that evaluate more than they strictly need to can cause the wrong error to be logged.
Describe the solution you'd like
A data structure that describes the pretty-printable "document". You might call this an embedded markup language, but that sounds more complex than it is.
Format
_type = "pretty"
marks the interface to Nix'sthrow
,abort
andtrace
.mkColored = c: { _type = "pretty"; color = "red"; content = c; }
: render content with specified ANSI color in addition to any other stylesmkPrettyValue = v: { _type = "pretty"; value = v; }
: pretty-print a Nix value. This is where the robustness claim comes from. Currently error messages have to choose between providing information and being robust, as evaluating all (or more) of a bad value can cause a secondary exception that's printed as if it's the only error. Here we can choose to ignore that and print the parts that don't throw.mkBold = c: { _type = "pretty"; bold = true; content = c; }
: render content in bold (ANSI highlight) in addition to any other stylesmkLine = list: { _type = "pretty"; line = list; }
: render a concatenation ofpretty
items and stringsmkCode = c: { _type = "pretty"; code = true; }
: render as code (MVP: no color + bold). A semantic constructor like this is useful for alternative loggers that render to something more powerful than the ANSI terminal.{ _type = "fallback"; fallback = c; }
, a forward compatibility measure. Render thefallback
if the rest of the attrset is not understood. Only Nixpkgslib
needs this constructor.wl-pprint
with its primitives_type = "pretty"
document when any of the interpolated strings is a document.unsafeGetAttrPos
mkCode
with Nix expression syntax highlightingmkPrettyValue
: don't traverse too deeplyBackcompat
Doing this through Nixpkgs
lib
has the advantage that it can add backward compatibility attributes that are ignored by the renderer.throw
/abort
Note the current behavior:
By adding an appropriate
outPath
or__toString
attribute to these constructors, we can make the messages render themselves as needed. Won't be quite as pretty, but capable of rendering the MVP level constructors.trace
Old implementations of
trace
will pretty-print any non-string value. It's impolite to just throw these internal attributes into someone's face, but that's about the worst that will happen. Just avoidtrace
for a while, until most everyone has a better Nix.string interpolation
This is not in the MVP part of the proposal, but does suggest a forward compatibility measure.
Although a non-backcompat constructor wouldn't steal any semantics:
... a version that does support backcompat would break the meaning of some hypothetical expressions
Breaking the interpolation behavior only for values with signature
_type = "pretty"; __toString; ...
seems acceptable to me, but we can choose not to do it and have an equally useful feature later, when Nixpkgs' minversion progresses beyond the point where the__toString
isn't necessary for compatibility anymore.However, at that point, some code may rely on the interpolation of documents to produce actual strings. To prevent that, we may want to forbid the interpolation of
_type = "pretty";
values into strings, as part of the MVP; reserved syntax.Describe alternatives you've considered
Interpret the throw and trace arguments as markdown. This would be ambiguous, not extensible and doesn't help with spatial layout.
Additional context
❤️ structured data
Priorities
Add 👍 to issues you find important.
The text was updated successfully, but these errors were encountered: