difftreelog
feat(evaluator) readable error messages
in: master
6 files changed
crates/jrsonnet-evaluator/Cargo.tomldiffbeforeafterboth1[package]2name = "jrsonnet-evaluator"3description = "jsonnet interpreter"4version = "0.3.0"5authors = ["Лач <iam@lach.pw>"]6license = "MIT"7edition = "2018"89# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html1011[features]12default = ["serialized-stdlib", "faster", "explaining-traces", "serde-json"]13# Serializes standard library AST instead of parsing them every run14serialized-stdlib = ["serde", "bincode", "jrsonnet-parser/deserialize"]15# Allow to convert Val into serde_json::Value and backwards16serde-json = ["serde", "serde_json"]17# Same as above, but with generated code instead of serde. Reduces memory usage, but increases binary size and compilation time18codegenerated-stdlib = []19# Replace some standard library functions with faster implementations (I.e manifestJsonEx)20# Library works fine without this feature, but requires more memory and time for std function calls21faster = []22# Rustc-like trace visualization23explaining-traces = ["annotate-snippets"]2425# Unlocks extra features, but works only on unstable26unstable = []2728[dependencies]29jrsonnet-parser = { path = "../jrsonnet-parser", version = "0.3.0" }30jrsonnet-stdlib = { path = "../jrsonnet-stdlib", version = "0.3.0" }31pathdiff = "0.2.0"3233closure = "0.3.0"34indexmap = "1.5.1"3536md5 = "0.7.0"37base64 = "0.12.3"38rustc-hash = "1.1.0"3940# Serialized stdlib41[dependencies.serde]42version = "1.0.115"43optional = true44[dependencies.bincode]45version = "1.3.1"46optional = true4748# Serde json49[dependencies.serde_json]50version = "1.0.57"51optional = true5253# Explaining traces54[dependencies.annotate-snippets]55version = "0.9.0"56optional = true5758[build-dependencies]59jrsonnet-parser = { path = "../jrsonnet-parser", features = ["dump", "serialize", "deserialize"], version = "0.3.0" }60jrsonnet-stdlib = { path = "../jrsonnet-stdlib", version = "0.3.0" }61structdump = "0.1.2"62serde = "1.0.115"63bincode = "1.3.1"crates/jrsonnet-evaluator/src/builtin/format.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/builtin/format.rs
+++ b/crates/jrsonnet-evaluator/src/builtin/format.rs
@@ -2,16 +2,23 @@
#![allow(clippy::too_many_arguments)]
use crate::{error::Error::*, throw, LocError, ObjValue, Result, Val, ValType};
+use thiserror::Error;
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, Error)]
pub enum FormatError {
+ #[error("truncated format code")]
TruncatedFormatCode,
+ #[error("unrecognized conversion type: {0}")]
UnrecognizedConversionType(char),
+ #[error("not enough values")]
NotEnoughValues,
+ #[error("cannot use * width with object")]
CannotUseStarWidthWithObject,
+ #[error("mapping keys required")]
MappingKeysRequired,
+ #[error("no such format field: {0}")]
NoSuchFormatField(Rc<str>),
}
crates/jrsonnet-evaluator/src/builtin/sort.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/builtin/sort.rs
+++ b/crates/jrsonnet-evaluator/src/builtin/sort.rs
@@ -4,9 +4,11 @@
};
use std::rc::Rc;
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, thiserror::Error)]
pub enum SortError {
+ #[error("sort key should be string or number")]
SortKeyShouldBeStringOrNumber,
+ #[error("sort elements should have equal types")]
SortElementsShouldHaveEqualType,
}
crates/jrsonnet-evaluator/src/ctx.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/ctx.rs
+++ b/crates/jrsonnet-evaluator/src/ctx.rs
@@ -63,7 +63,7 @@
.bindings
.get(&name)
.cloned()
- .ok_or_else(|| UnknownVariable(name))?)
+ .ok_or_else(|| VariableIsNotDefined(name))?)
}
pub fn into_future(self, ctx: FutureContext) -> Self {
{
crates/jrsonnet-evaluator/src/error.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/error.rs
+++ b/crates/jrsonnet-evaluator/src/error.rs
@@ -4,75 +4,117 @@
};
use jrsonnet_parser::{BinaryOpType, ExprLocation, UnaryOpType};
use std::{path::PathBuf, rc::Rc};
+use thiserror::Error;
-#[derive(Debug, Clone)]
+#[derive(Error, Debug, Clone)]
pub enum Error {
+ #[error("intrinsic not found: {0}.{1}")]
IntrinsicNotFound(Rc<str>, Rc<str>),
+ #[error("argument reordering in intrisics not supported yet")]
IntrinsicArgumentReorderingIsNotSupportedYet,
+ #[error("operator {0} does not operate on type {1}")]
UnaryOperatorDoesNotOperateOnType(UnaryOpType, ValType),
+ #[error("binary operation {1} {0} {2} is not implemented")]
BinaryOperatorDoesNotOperateOnValues(BinaryOpType, ValType, ValType),
+ #[error("no top level object in this context")]
NoTopLevelObjectFound,
+ #[error("self is only usable inside objects")]
CantUseSelfOutsideOfObject,
+ #[error("super is only usable inside objects")]
CantUseSuperOutsideOfObject,
+ #[error("for loop can only iterate over arrays")]
InComprehensionCanOnlyIterateOverArray,
+ #[error("array out of bounds: {0} is not within [0,{1})")]
ArrayBoundsError(usize, usize),
+ #[error("assert failed: {0}")]
AssertionFailed(Rc<str>),
- VariableIsNotDefined(String),
+ #[error("variable is not defined: {0}")]
+ VariableIsNotDefined(Rc<str>),
+ #[error("type mismatch: expected {2}, got {1:?} {0}")]
TypeMismatch(&'static str, Vec<ValType>, ValType),
+ #[error("no such field: {0}")]
NoSuchField(Rc<str>),
- UnknownVariable(Rc<str>),
-
+ #[error("only functions can be called, got {0}")]
OnlyFunctionsCanBeCalledGot(ValType),
+ #[error("parameter {0} is not defined")]
UnknownFunctionParameter(String),
+ #[error("argument {0} is already bound")]
BindingParameterASecondTime(Rc<str>),
+ #[error("too many args, function has {0}")]
TooManyArgsFunctionHas(usize),
+ #[error("founction argument is not passed: {0}")]
FunctionParameterNotBoundInCall(Rc<str>),
+ #[error("external variable is not defined: {0}")]
UndefinedExternalVariable(Rc<str>),
+ #[error("native is not defined: {0}")]
UndefinedExternalFunction(Rc<str>),
+ #[error("field name should be string, got {0}")]
FieldMustBeStringGot(ValType),
+ #[error("attempted to index array with string {0}")]
AttemptedIndexAnArrayWithString(Rc<str>),
+ #[error("{0} index type should be {1}, got {2}")]
ValueIndexMustBeTypeGot(ValType, ValType, ValType),
+ #[error("cant index into {0}")]
CantIndexInto(ValType),
+ #[error("super can't be used standalone")]
StandaloneSuper,
+ #[error("can't resolve {1} from {0}")]
ImportFileNotFound(PathBuf, PathBuf),
+ #[error("resolved file not found: {0}")]
ResolvedFileNotFound(PathBuf),
+ #[error("imported file is not valid utf-8: {0:?}")]
ImportBadFileUtf8(PathBuf),
+ #[error("tried to import {1} from {0}, but imports is not supported")]
ImportNotSupported(PathBuf, PathBuf),
+ #[error("syntax error")]
ImportSyntaxError {
path: Rc<PathBuf>,
source_code: Rc<str>,
error: Box<jrsonnet_parser::ParseError>,
},
+ #[error("runtime error: {0}")]
RuntimeError(Rc<str>),
+ #[error("stack overflow, try to reduce recursion, or set --max-stack to bigger value")]
StackOverflow,
+ #[error("tried to index by fractional value")]
FractionalIndex,
+ #[error("attempted to divide by zero")]
DivisionByZero,
+ #[error("string manifest output is not an string")]
StringManifestOutputIsNotAString,
+ #[error("stream manifest output is not an array")]
StreamManifestOutputIsNotAArray,
+ #[error("multi manifest output is not an object")]
MultiManifestOutputIsNotAObject,
+ #[error("cant recurse stream manifest")]
StreamManifestOutputCannotBeRecursed,
+ #[error("stream manifest output cannot consist of raw strings")]
StreamManifestCannotNestString,
+ #[error("{0}")]
ImportCallbackError(String),
+ #[error("invalid unicode codepoint: {0}")]
InvalidUnicodeCodepointGot(u32),
- Format(FormatError),
- Sort(SortError),
+ #[error("format error: {0}")]
+ Format(#[from] FormatError),
+ #[error("sort error: {0}")]
+ Sort(#[from] SortError),
}
impl From<Error> for LocError {
fn from(e: Error) -> Self {
crates/jrsonnet-evaluator/src/trace/mod.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/trace/mod.rs
+++ b/crates/jrsonnet-evaluator/src/trace/mod.rs
@@ -86,7 +86,7 @@
evaluation_state: &EvaluationState,
error: &LocError,
) -> Result<(), std::fmt::Error> {
- writeln!(out, "{:?}", error.error())?;
+ writeln!(out, "{}", error.error())?;
let file_names = error
.trace()
.0
@@ -132,7 +132,7 @@
evaluation_state: &EvaluationState,
error: &LocError,
) -> Result<(), std::fmt::Error> {
- writeln!(out, "{:?}", error.error())?;
+ writeln!(out, "{}", error.error())?;
for (i, item) in error.trace().0.iter().enumerate() {
if i != 0 {
writeln!(out)?;
@@ -171,7 +171,7 @@
display_list::{DisplayList, FormatOptions},
snippet::{AnnotationType, Slice, Snippet, SourceAnnotation},
};
- writeln!(out, "{:?}", error.error())?;
+ writeln!(out, "{}", error.error())?;
let trace = &error.trace();
for item in trace.0.iter() {
let desc = &item.desc;