1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
use crate::{ builtin::{format::FormatError, sort::SortError}, typed::TypeLocError, }; use jrsonnet_gc::Trace; use jrsonnet_interner::IStr; use jrsonnet_parser::{BinaryOpType, ExprLocation, UnaryOpType}; use jrsonnet_types::ValType; use std::{ path::{Path, PathBuf}, rc::Rc, }; use thiserror::Error; #[derive(Error, Debug, Clone, Trace)] #[trivially_drop] pub enum Error { #[error("intrinsic not found: {0}")] IntrinsicNotFound(IStr), #[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("no super found")] NoSuperFound, #[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(IStr), #[error("variable is not defined: {0}")] VariableIsNotDefined(IStr), #[error("type mismatch: expected {}, got {2} {0}", .1.iter().map(|e| format!("{}", e)).collect::<Vec<_>>().join(", "))] TypeMismatch(&'static str, Vec<ValType>, ValType), #[error("no such field: {0}")] NoSuchField(IStr), #[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(IStr), #[error("too many args, function has {0}")] TooManyArgsFunctionHas(usize), #[error("founction argument is not passed: {0}")] FunctionParameterNotBoundInCall(IStr), #[error("external variable is not defined: {0}")] UndefinedExternalVariable(IStr), #[error("native is not defined: {0}")] UndefinedExternalFunction(IStr), #[error("field name should be string, got {0}")] FieldMustBeStringGot(ValType), #[error("attempted to index array with string {0}")] AttemptedIndexAnArrayWithString(IStr), #[error("{0} index type should be {1}, got {2}")] ValueIndexMustBeTypeGot(ValType, ValType, ValType), #[error("cant index into {0}")] CantIndexInto(ValType), #[error("{0} is not indexable")] ValueIsNotIndexable(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, expected one of {}, got {:?}", .error.expected, .source_code.chars().nth(error.location.offset).map(|c| c.to_string()).unwrap_or_else(|| "EOF".into()) )] ImportSyntaxError { path: Rc<Path>, source_code: IStr, #[unsafe_ignore_trace] error: Box<jrsonnet_parser::ParseError>, }, #[error("runtime error: {0}")] RuntimeError(IStr), #[error("stack overflow, try to reduce recursion, or set --max-stack to bigger value")] StackOverflow, #[error("infinite recursion detected")] RecursiveLazyValueEvaluation, #[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), #[error("format error: {0}")] Format(#[from] FormatError), #[error("type error: {0}")] TypeError(TypeLocError), #[error("sort error: {0}")] Sort(#[from] SortError), #[cfg(feature = "anyhow-error")] #[error(transparent)] Other(Rc<anyhow::Error>), } #[cfg(feature = "anyhow-error")] impl From<anyhow::Error> for LocError { fn from(e: anyhow::Error) -> Self { Self::new(Error::Other(Rc::new(e))) } } impl From<Error> for LocError { fn from(e: Error) -> Self { Self::new(e) } } #[derive(Clone, Debug, Trace)] #[trivially_drop] pub struct StackTraceElement { pub location: Option<ExprLocation>, pub desc: String, } #[derive(Debug, Clone, Trace)] #[trivially_drop] pub struct StackTrace(pub Vec<StackTraceElement>); #[derive(Debug, Clone, Trace)] #[trivially_drop] pub struct LocError(Box<(Error, StackTrace)>); impl LocError { pub fn new(e: Error) -> Self { Self(Box::new((e, StackTrace(vec![])))) } pub const fn error(&self) -> &Error { &(self.0).0 } pub fn error_mut(&mut self) -> &mut Error { &mut (self.0).0 } pub const fn trace(&self) -> &StackTrace { &(self.0).1 } pub fn trace_mut(&mut self) -> &mut StackTrace { &mut (self.0).1 } } pub type Result<V> = std::result::Result<V, LocError>; #[macro_export] macro_rules! throw { ($e: expr) => { return Err($e.into()); }; }