forked from mirrors/jj
revset: add origin field to RevsetParseError to chain alias errors
This could be embedded in a variant of RevsetParseErrorKind, but I want to keep the enum comparable.
This commit is contained in:
parent
7632466cc0
commit
5df25cd834
2 changed files with 33 additions and 1 deletions
|
@ -198,6 +198,7 @@ pub struct RevsetParser;
|
||||||
pub struct RevsetParseError {
|
pub struct RevsetParseError {
|
||||||
kind: RevsetParseErrorKind,
|
kind: RevsetParseErrorKind,
|
||||||
pest_error: Option<Box<pest::error::Error<Rule>>>,
|
pest_error: Option<Box<pest::error::Error<Rule>>>,
|
||||||
|
origin: Option<Box<RevsetParseError>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Error, PartialEq, Eq)]
|
#[derive(Debug, Error, PartialEq, Eq)]
|
||||||
|
@ -219,6 +220,7 @@ impl RevsetParseError {
|
||||||
RevsetParseError {
|
RevsetParseError {
|
||||||
kind,
|
kind,
|
||||||
pest_error: None,
|
pest_error: None,
|
||||||
|
origin: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,12 +234,36 @@ impl RevsetParseError {
|
||||||
RevsetParseError {
|
RevsetParseError {
|
||||||
kind,
|
kind,
|
||||||
pest_error: Some(Box::new(err)),
|
pest_error: Some(Box::new(err)),
|
||||||
|
origin: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn with_span_and_origin(
|
||||||
|
kind: RevsetParseErrorKind,
|
||||||
|
span: pest::Span<'_>,
|
||||||
|
origin: Self,
|
||||||
|
) -> Self {
|
||||||
|
let err = pest::error::Error::new_from_span(
|
||||||
|
pest::error::ErrorVariant::CustomError {
|
||||||
|
message: kind.to_string(),
|
||||||
|
},
|
||||||
|
span,
|
||||||
|
);
|
||||||
|
RevsetParseError {
|
||||||
|
kind,
|
||||||
|
pest_error: Some(Box::new(err)),
|
||||||
|
origin: Some(Box::new(origin)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn kind(&self) -> &RevsetParseErrorKind {
|
pub fn kind(&self) -> &RevsetParseErrorKind {
|
||||||
&self.kind
|
&self.kind
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Original parsing error which typically occurred in an alias expression.
|
||||||
|
pub fn origin(&self) -> Option<&Self> {
|
||||||
|
self.origin.as_deref()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<pest::error::Error<Rule>> for RevsetParseError {
|
impl From<pest::error::Error<Rule>> for RevsetParseError {
|
||||||
|
@ -245,6 +271,7 @@ impl From<pest::error::Error<Rule>> for RevsetParseError {
|
||||||
RevsetParseError {
|
RevsetParseError {
|
||||||
kind: RevsetParseErrorKind::SyntaxError,
|
kind: RevsetParseErrorKind::SyntaxError,
|
||||||
pest_error: Some(Box::new(err)),
|
pest_error: Some(Box::new(err)),
|
||||||
|
origin: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -261,6 +288,9 @@ impl fmt::Display for RevsetParseError {
|
||||||
|
|
||||||
impl error::Error for RevsetParseError {
|
impl error::Error for RevsetParseError {
|
||||||
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
|
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
|
||||||
|
if let Some(e) = self.origin() {
|
||||||
|
return Some(e as &dyn error::Error);
|
||||||
|
}
|
||||||
match &self.kind {
|
match &self.kind {
|
||||||
// SyntaxError is a wrapper for pest::error::Error.
|
// SyntaxError is a wrapper for pest::error::Error.
|
||||||
RevsetParseErrorKind::SyntaxError => {
|
RevsetParseErrorKind::SyntaxError => {
|
||||||
|
|
|
@ -16,6 +16,7 @@ use std::collections::{HashSet, VecDeque};
|
||||||
use std::env::ArgsOs;
|
use std::env::ArgsOs;
|
||||||
use std::ffi::OsString;
|
use std::ffi::OsString;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
use std::iter;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -175,7 +176,8 @@ impl From<GitExportError> for CommandError {
|
||||||
|
|
||||||
impl From<RevsetParseError> for CommandError {
|
impl From<RevsetParseError> for CommandError {
|
||||||
fn from(err: RevsetParseError) -> Self {
|
fn from(err: RevsetParseError) -> Self {
|
||||||
user_error(format!("Failed to parse revset: {err}"))
|
let message = iter::successors(Some(&err), |e| e.origin()).join("\n");
|
||||||
|
user_error(format!("Failed to parse revset: {message}"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue