Some more error message improvements

This commit is contained in:
elkowar 2021-08-14 11:58:04 +02:00
parent c0581e7769
commit f7f718b94a
No known key found for this signature in database
GPG key ID: E321AD71B1D1F27F
7 changed files with 54 additions and 32 deletions

View file

@ -46,7 +46,7 @@ pub fn initialize_server(paths: EwwPaths, action: Option<DaemonCommand>) -> Resu
gtk::init()?;
log::info!("Initializing script var handler");
log::debug!("Initializing script var handler");
let script_var_handler = script_var_handler::init(ui_send.clone());
let mut app = app::App {
@ -107,7 +107,7 @@ fn init_async_part(paths: EwwPaths, ui_send: UnboundedSender<app::DaemonCommand>
tokio::spawn(async move {
// Wait for application exit event
let _ = crate::application_lifecycle::recv_exit().await;
log::info!("Forward task received exit event");
log::debug!("Forward task received exit event");
// Then forward that to the application
let _ = ui_send.send(app::DaemonCommand::KillServer);
})

View file

@ -29,7 +29,7 @@ impl FromAstElementContent for WidgetDefinition {
let (name_span, name) = iter.expect_symbol().note(EXPECTED_WIDGET_DEF_FORMAT)?;
let (args_span, expected_args) = iter
.expect_array()
.wrong_expr_type_to(|_| FormFormatError::WidgetDefArglistMissing(name_span.point_span_at_end()))
.wrong_expr_type_to(|_, _| Some(FormFormatError::WidgetDefArglistMissing(name_span.point_span_at_end())))
.note(EXPECTED_WIDGET_DEF_FORMAT)?;
let expected_args = expected_args.into_iter().map(|x| x.as_symbol().map(AttrName)).collect::<AstResult<_>>()?;
let widget = iter.expect_any().note(EXPECTED_WIDGET_DEF_FORMAT).and_then(WidgetUse::from_ast)?;

View file

@ -4,7 +4,7 @@ use simplexpr::SimplExpr;
use crate::{
config::attributes::AttrEntry,
error::AstResult,
error::{AstError, AstResult},
parser::{ast::Ast, ast_iterator::AstIterator, from_ast::FromAst},
};
use eww_shared_util::{AttrName, Span, VarName};
@ -34,21 +34,7 @@ impl FromAst for WidgetUse {
fn from_ast(e: Ast) -> AstResult<Self> {
let span = e.span();
if let Ok(value) = e.clone().as_simplexpr() {
Ok(Self {
name: "label".to_string(),
name_span: span.point_span(),
attrs: Attributes::new(
span,
maplit::hashmap! {
AttrName("text".to_string()) => AttrEntry::new(
span,
Ast::SimplExpr(span.into(), value.clone())
)
},
),
children: Vec::new(),
span,
})
Ok(label_from_simplexpr(value, span))
} else {
let mut iter = e.try_ast_iter()?;
let (name_span, name) = iter.expect_symbol()?;
@ -58,3 +44,21 @@ impl FromAst for WidgetUse {
}
}
}
fn label_from_simplexpr(value: SimplExpr, span: Span) -> WidgetUse {
WidgetUse {
name: "label".to_string(),
name_span: span.point_span(),
attrs: Attributes::new(
span,
maplit::hashmap! {
AttrName("text".to_string()) => AttrEntry::new(
span,
Ast::SimplExpr(span.into(), value.clone())
)
},
),
children: Vec::new(),
span,
}
}

View file

@ -34,6 +34,9 @@ pub enum AstError {
#[error("Expected element {1}, but read {2}")]
MismatchedElementName(Span, String, String),
#[error("Keyword `{1}` is missing a value")]
DanglingKeyword(Span, String),
#[error("Included file not found {}", .0.path)]
IncludedFileNotFound(Include),
@ -81,9 +84,11 @@ impl AstError {
AstError::ParseError { file_id, source: err }
}
pub fn wrong_expr_type_to(self, f: impl FnOnce(Span) -> FormFormatError) -> AstError {
pub fn wrong_expr_type_to<T: Into<AstError>>(self, f: impl FnOnce(Span, AstType) -> Option<T>) -> AstError {
match self {
AstError::WrongExprType(span, ..) => AstError::FormFormatError(f(span.point_span())),
AstError::WrongExprType(span, expected, got) => {
f(span.point_span(), got).map(|x| x.into()).unwrap_or_else(|| AstError::WrongExprType(span, expected, got))
}
AstError::ErrorNote(s, err) => AstError::ErrorNote(s, Box::new(err.wrong_expr_type_to(f))),
other => other,
}
@ -98,6 +103,7 @@ impl Spanned for AstError {
AstError::WrongExprType(span, ..) => *span,
AstError::NotAValue(span, ..) => *span,
AstError::MismatchedElementName(span, ..) => *span,
AstError::DanglingKeyword(span, _) => *span,
AstError::AttrError(err) => err.span(),
AstError::Other(span, ..) => *span,
AstError::ConversionError(err) => err.value.span(),
@ -138,8 +144,9 @@ pub trait AstResultExt<T> {
fn context_label(self, label_span: Span, context: &str) -> AstResult<T>;
fn note(self, note: &str) -> AstResult<T>;
/// Map any [AstError::WrongExprType]s error to a [FormFormatError]
fn wrong_expr_type_to(self, f: impl FnOnce(Span) -> FormFormatError) -> AstResult<T>;
/// Map any [AstError::WrongExprType]s error to any other Into<AstError> (such as a [FormFormatError])
/// If the provided closure returns `None`, the error will be kept unmodified
fn wrong_expr_type_to<E: Into<AstError>>(self, f: impl FnOnce(Span, AstType) -> Option<E>) -> AstResult<T>;
}
impl<T> AstResultExt<T> for AstResult<T> {
@ -151,7 +158,7 @@ impl<T> AstResultExt<T> for AstResult<T> {
self.map_err(|e| e.note(note))
}
fn wrong_expr_type_to(self, f: impl FnOnce(Span) -> FormFormatError) -> AstResult<T> {
fn wrong_expr_type_to<E: Into<AstError>>(self, f: impl FnOnce(Span, AstType) -> Option<E>) -> AstResult<T> {
self.map_err(|err| err.wrong_expr_type_to(f))
}
}

View file

@ -89,7 +89,7 @@ impl ToDiagnostic for AstError {
AstError::WrongExprType(span, expected, actual) => gen_diagnostic! {
msg = "Wrong type of expression",
label = span => format!("Expected a `{}` here", expected),
note = format!("Expected: {}\nGot: {}", expected, actual),
note = format!("Expected: {}\n Got: {}", expected, actual),
},
AstError::NotAValue(span, actual) => gen_diagnostic! {
msg = format!("Expected value, but got `{}`", actual),
@ -101,7 +101,7 @@ impl ToDiagnostic for AstError {
AstError::MismatchedElementName(span, expected, got) => gen_diagnostic! {
msg = format!("Expected element `{}`, but found `{}`", expected, got),
label = span => format!("Expected `{}` here", expected),
note = format!("Expected: {}\nGot: {}", expected, got),
note = format!("Expected: {}\n Got: {}", expected, got),
},
AstError::ErrorContext { label_span, context, main_err } => {
main_err.to_diagnostic().with_label(span_to_secondary_label(*label_span).with_message(context))
@ -120,6 +120,10 @@ impl ToDiagnostic for AstError {
label = extra_nodes_span => "these elements must not be here",
note = "Consider wrapping the elements in some container element",
},
AstError::DanglingKeyword(span, keyword) => gen_diagnostic! {
msg = self,
label = span => "No value provided for this",
},
AstError::ErrorNote(note, source) => source.to_diagnostic().with_notes(vec![note.to_string()]),
AstError::ValidationError(source) => source.to_diagnostic(),
AstError::NoMoreElementsExpected(span) => gen_diagnostic!(self, span),

View file

@ -27,7 +27,10 @@ pub enum AstType {
impl Display for AstType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self)
match self {
AstType::IntoPrimitive => write!(f, "primitive"),
_ => write!(f, "{:?}", self),
}
}
}

View file

@ -77,7 +77,7 @@ impl<I: Iterator<Item = Ast>> AstIterator<I> {
}
pub fn expect_key_values(&mut self) -> AstResult<Attributes> {
parse_key_values(self)
parse_key_values(self, true)
}
pub fn put_back(&mut self, ast: Ast) {
@ -98,7 +98,7 @@ impl<I: Iterator<Item = Ast>> Iterator for AstIterator<I> {
}
/// Parse consecutive `:keyword value` pairs from an expression iterator into an [Attributes].
fn parse_key_values(iter: &mut AstIterator<impl Iterator<Item = Ast>>) -> AstResult<Attributes> {
fn parse_key_values(iter: &mut AstIterator<impl Iterator<Item = Ast>>, fail_on_dangling_kw: bool) -> AstResult<Attributes> {
let mut data = HashMap::new();
let mut attrs_span = iter.remaining_span.point_span();
loop {
@ -110,9 +110,13 @@ fn parse_key_values(iter: &mut AstIterator<impl Iterator<Item = Ast>>) -> AstRes
data.insert(AttrName(kw), attr_value);
}
None => {
iter.iter.put_back(Ast::Keyword(key_span, kw));
attrs_span.1 = iter.remaining_span.0;
return Ok(Attributes::new(attrs_span, data));
if fail_on_dangling_kw {
return Err(AstError::DanglingKeyword(key_span, kw));
} else {
iter.iter.put_back(Ast::Keyword(key_span, kw));
attrs_span.1 = iter.remaining_span.0;
return Ok(Attributes::new(attrs_span, data));
}
}
},
next => {