Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(refactor): merge 'ExpressionError' and 'ExpressionError2' #554

Merged
merged 1 commit into from
Nov 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 2 additions & 52 deletions src/compiler/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,11 @@ pub use query::{Query, Target};
pub use unary::Unary;
pub use variable::Variable;

use crate::diagnostic::{DiagnosticMessage, Label, Note};
use crate::value::Value;

use super::state::{TypeInfo, TypeState};
use super::{Context, Span, TypeDef};
pub use super::{ExpressionError2, Resolved};
use super::{Context, TypeDef};
pub use super::{ExpressionError, Resolved};

mod abort;
mod array;
Expand Down Expand Up @@ -369,52 +368,3 @@ impl From<Value> for Expr {
}
}
}

// -----------------------------------------------------------------------------

#[derive(thiserror::Error, Debug)]
pub enum ExpressionError {
#[error("unhandled error")]
Fallible { span: Span },

#[error("expression type unavailable")]
Missing { span: Span, feature: &'static str },
}

impl DiagnosticMessage for ExpressionError {
fn code(&self) -> usize {
use ExpressionError::{Fallible, Missing};

match self {
Fallible { .. } => 100,
Missing { .. } => 900,
}
}

fn labels(&self) -> Vec<Label> {
use ExpressionError::{Fallible, Missing};

match self {
Fallible { span } => vec![
Label::primary("expression can result in runtime error", span),
Label::context("handle the error case to ensure runtime success", span),
],
Missing { span, feature } => vec![
Label::primary("expression type is disabled in this version of vrl", span),
Label::context(
format!("build vrl using the `{feature}` feature to enable it"),
span,
),
],
}
}

fn notes(&self) -> Vec<Note> {
use ExpressionError::{Fallible, Missing};

match self {
Fallible { .. } => vec![Note::SeeErrorDocs],
Missing { .. } => vec![],
}
}
}
6 changes: 3 additions & 3 deletions src/compiler/expression/abort.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::fmt;

use crate::compiler::{
expression::{ExpressionError2, Resolved},
expression::{ExpressionError, Resolved},
state::{TypeInfo, TypeState},
value::{Kind, VrlValueConvert},
Context, Expression, Span, TypeDef,
Expand Down Expand Up @@ -53,12 +53,12 @@ impl Expression for Abort {
let message = self
.message
.as_ref()
.map::<Result<_, ExpressionError2>, _>(|expr| {
.map::<Result<_, ExpressionError>, _>(|expr| {
Ok(expr.resolve(ctx)?.try_bytes_utf8_lossy()?.to_string())
})
.transpose()?;

Err(ExpressionError2::Abort {
Err(ExpressionError::Abort {
span: self.span,
message,
})
Expand Down
10 changes: 6 additions & 4 deletions src/compiler/expression/function_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::{fmt, sync::Arc};

use crate::compiler::state::{TypeInfo, TypeState};
use crate::compiler::{
expression::{levenstein, ExpressionError2, FunctionArgument},
expression::{levenstein, ExpressionError, FunctionArgument},
function::{
closure::{self, VariableKind},
ArgumentList, Example, FunctionClosure, FunctionCompileContext, Parameter,
Expand Down Expand Up @@ -637,18 +637,20 @@ impl FunctionCall {
impl Expression for FunctionCall {
fn resolve(&self, ctx: &mut Context) -> Resolved {
self.expr.resolve(ctx).map_err(|err| match err {
ExpressionError2::Abort { .. } => {
ExpressionError::Abort { .. }
| ExpressionError::Fallible { .. }
| ExpressionError::Missing { .. } => {
// propagate the error
err
}
ExpressionError2::Error {
ExpressionError::Error {
message,
mut labels,
notes,
} => {
labels.push(Label::primary(message.clone(), self.span));

ExpressionError2::Error {
ExpressionError::Error {
message: format!(
r#"function call error for "{}" at ({}:{}): {}"#,
self.ident,
Expand Down
67 changes: 44 additions & 23 deletions src/compiler/expression_error.rs
Original file line number Diff line number Diff line change
@@ -1,36 +1,46 @@
use crate::diagnostic::{Diagnostic, DiagnosticMessage, Label, Note, Severity};
use ExpressionError::{Abort, Error, Fallible, Missing};

use crate::diagnostic::{Diagnostic, DiagnosticMessage, Label, Note, Severity, Span};
use crate::value::Value;

pub type Resolved = Result<Value, ExpressionError2>;
pub type Resolved = Result<Value, ExpressionError>;

// TODO: merge with [`expression::ExpressionError`]
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum ExpressionError2 {
pub enum ExpressionError {
Abort {
span: crate::diagnostic::Span,
span: Span,
message: Option<String>,
},
Error {
message: String,
labels: Vec<Label>,
notes: Vec<Note>,
},

Fallible {
span: Span,
},

Missing {
span: Span,
feature: &'static str,
},
}

impl std::fmt::Display for ExpressionError2 {
impl std::fmt::Display for ExpressionError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.message().fmt(f)
}
}

impl std::error::Error for ExpressionError2 {
impl std::error::Error for ExpressionError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
None
}
}

impl From<ExpressionError2> for Diagnostic {
fn from(error: ExpressionError2) -> Self {
impl From<ExpressionError> for Diagnostic {
fn from(error: ExpressionError) -> Self {
Self {
severity: Severity::Error,
code: error.code(),
Expand All @@ -41,55 +51,66 @@ impl From<ExpressionError2> for Diagnostic {
}
}

impl DiagnosticMessage for ExpressionError2 {
impl DiagnosticMessage for ExpressionError {
fn code(&self) -> usize {
0
match self {
Abort { .. } => 0,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Preserving existing behavior but we might want to revisit this code.

Error { .. } => 0,
Fallible { .. } => 100,
Missing { .. } => 900,
}
}

fn message(&self) -> String {
use ExpressionError2::Abort;
use ExpressionError2::Error;

match self {
Abort { message, .. } => message.clone().unwrap_or_else(|| "aborted".to_owned()),
Error { message, .. } => message.clone(),
Fallible { .. } => "unhandled error".to_string(),
Missing { .. } => "expression type unavailable".to_string(),
}
}

fn labels(&self) -> Vec<Label> {
use ExpressionError2::Abort;
use ExpressionError2::Error;

match self {
Abort { span, .. } => {
vec![Label::primary("aborted", span)]
}
Error { labels, .. } => labels.clone(),
Fallible { span } => vec![
Label::primary("expression can result in runtime error", span),
Label::context("handle the error case to ensure runtime success", span),
],
Missing { span, feature } => vec![
Label::primary("expression type is disabled in this version of vrl", span),
Label::context(
format!("build vrl using the `{feature}` feature to enable it"),
span,
),
],
}
}

fn notes(&self) -> Vec<Note> {
use ExpressionError2::Abort;
use ExpressionError2::Error;

match self {
Abort { .. } => vec![],
Error { notes, .. } => notes.clone(),
Fallible { .. } => vec![Note::SeeErrorDocs],
Missing { .. } => vec![],
}
}
}

impl From<String> for ExpressionError2 {
impl From<String> for ExpressionError {
fn from(message: String) -> Self {
ExpressionError2::Error {
ExpressionError::Error {
message,
labels: vec![],
notes: vec![],
}
}
}

impl From<&str> for ExpressionError2 {
impl From<&str> for ExpressionError {
fn from(message: &str) -> Self {
message.to_owned().into()
}
Expand Down
12 changes: 6 additions & 6 deletions src/compiler/function/closure.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::collections::BTreeMap;

use crate::compiler::ExpressionError2;
use crate::compiler::ExpressionError;
use crate::compiler::{
state::RuntimeState,
value::{Kind, VrlValueConvert},
Expand Down Expand Up @@ -149,7 +149,7 @@ pub struct Runner<'a, T> {

impl<'a, T> Runner<'a, T>
where
T: Fn(&mut Context) -> Result<Value, ExpressionError2>,
T: Fn(&mut Context) -> Result<Value, ExpressionError>,
{
pub fn new(variables: &'a [Ident], runner: T) -> Self {
Self { variables, runner }
Expand All @@ -165,7 +165,7 @@ where
ctx: &mut Context,
key: &str,
value: &Value,
) -> Result<Value, ExpressionError2> {
) -> Result<Value, ExpressionError> {
// TODO: we need to allow `LocalEnv` to take a mutable reference to
// values, instead of owning them.
let cloned_key = key.to_owned();
Expand Down Expand Up @@ -195,7 +195,7 @@ where
ctx: &mut Context,
index: usize,
value: &Value,
) -> Result<Value, ExpressionError2> {
) -> Result<Value, ExpressionError> {
// TODO: we need to allow `LocalEnv` to take a mutable reference to
// values, instead of owning them.
let cloned_value = value.clone();
Expand All @@ -221,7 +221,7 @@ where
/// value of the closure after completion.
///
/// See `run_key_value` and `run_index_value` for immutable alternatives.
pub fn map_key(&self, ctx: &mut Context, key: &mut KeyString) -> Result<(), ExpressionError2> {
pub fn map_key(&self, ctx: &mut Context, key: &mut KeyString) -> Result<(), ExpressionError> {
// TODO: we need to allow `LocalEnv` to take a mutable reference to
// values, instead of owning them.
let cloned_key = key.clone();
Expand All @@ -242,7 +242,7 @@ where
/// value of the closure after completion.
///
/// See `run_key_value` and `run_index_value` for immutable alternatives.
pub fn map_value(&self, ctx: &mut Context, value: &mut Value) -> Result<(), ExpressionError2> {
pub fn map_value(&self, ctx: &mut Context, value: &mut Value) -> Result<(), ExpressionError> {
// TODO: we need to allow `LocalEnv` to take a mutable reference to
// values, instead of owning them.
let cloned_value = value.clone();
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ pub use compiler::{CompilationResult, Compiler};
pub use context::Context;
pub use datetime::TimeZone;
pub use expression::{Expression, FunctionExpression};
pub use expression_error::{ExpressionError2, Resolved};
pub use expression_error::{ExpressionError, Resolved};
pub use function::{Function, Parameter};
pub use program::{Program, ProgramInfo};
pub use state::{TypeInfo, TypeState};
Expand Down
6 changes: 3 additions & 3 deletions src/compiler/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pub use bytes::Bytes;
pub use indoc::indoc;
pub use ordered_float::NotNan;

pub use crate::{expr, func_args, test_function, test_type_def};
// macros
pub use crate::diagnostic::{DiagnosticMessage, Note, Span};
pub use crate::value::{
Expand All @@ -12,7 +13,6 @@ pub use crate::value::{
value::IterItem,
KeyString, Kind, ObjectMap, Value, ValueRegex,
};
pub use crate::{expr, func_args, test_function, test_type_def};

pub use super::Resolved;
pub use super::{
Expand All @@ -23,8 +23,8 @@ pub use super::{
state::{self, TypeInfo, TypeState},
type_def,
value::{kind, ValueError, VrlValueArithmetic, VrlValueConvert},
Context, Expression, ExpressionError2, Function, FunctionExpression, Parameter, TimeZone,
Context, Expression, ExpressionError, Function, FunctionExpression, Parameter, TimeZone,
TypeDef,
};

pub type ExpressionResult<T> = Result<T, ExpressionError2>;
pub type ExpressionResult<T> = Result<T, ExpressionError>;
14 changes: 8 additions & 6 deletions src/compiler/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::{error::Error, fmt};
use crate::path::OwnedTargetPath;
use crate::value::Value;

use super::ExpressionError2;
use super::ExpressionError;
use super::TimeZone;
use super::{state, Context, Program, Target};

Expand All @@ -22,15 +22,15 @@ pub enum Terminate {
/// This is an intentional termination that does not result in an
/// `Ok(Value)` result, but should neither be interpreted as an unexpected
/// outcome.
Abort(ExpressionError2),
Abort(ExpressionError),

/// An unexpected program termination.
Error(ExpressionError2),
Error(ExpressionError),
}

impl Terminate {
#[must_use]
pub fn get_expression_error(self) -> ExpressionError2 {
pub fn get_expression_error(self) -> ExpressionError {
match self {
Terminate::Abort(error) => error,
Terminate::Error(error) => error,
Expand Down Expand Up @@ -94,8 +94,10 @@ impl Runtime {
let mut ctx = Context::new(target, &mut self.state, timezone);

program.resolve(&mut ctx).map_err(|err| match err {
ExpressionError2::Abort { .. } => Terminate::Abort(err),
err @ ExpressionError2::Error { .. } => Terminate::Error(err),
ExpressionError::Abort { .. }
| ExpressionError::Fallible { .. }
| ExpressionError::Missing { .. } => Terminate::Abort(err),
err @ ExpressionError::Error { .. } => Terminate::Error(err),
})
}
}
Loading