error.rs
257 lines
| 8.9 KiB
| application/rls-services+xml
|
RustLexer
|
r45592 | use crate::exitcode; | ||
|
r47165 | use crate::ui::utf8_to_local; | ||
|
r45592 | use crate::ui::UiError; | ||
|
r46598 | use format_bytes::format_bytes; | ||
|
r47165 | use hg::operations::{ | ||
CatRevError, DebugDataError, FindRootError, ListDirstateTrackedFilesError, | ||||
ListRevTrackedFilesError, | ||||
}; | ||||
|
r46536 | use hg::requirements::RequirementsError; | ||
|
r45920 | use hg::utils::files::get_bytes_from_path; | ||
|
r45592 | use std::convert::From; | ||
|
r45920 | use std::path::PathBuf; | ||
|
r45592 | |||
/// The kind of command error | ||||
|
r47164 | #[derive(Debug, derive_more::From)] | ||
|
r47163 | pub enum CommandError { | ||
|
r45592 | /// The root of the repository cannot be found | ||
|
r45920 | RootNotFound(PathBuf), | ||
|
r45592 | /// The current directory cannot be found | ||
|
r45920 | CurrentDirNotFound(std::io::Error), | ||
|
r46536 | /// `.hg/requires` | ||
|
r47164 | #[from] | ||
|
r46536 | RequirementsError(RequirementsError), | ||
|
r45592 | /// The standard output stream cannot be written to | ||
StdoutError, | ||||
/// The standard error stream cannot be written to | ||||
StderrError, | ||||
|
r45923 | /// The command aborted | ||
Abort(Option<Vec<u8>>), | ||||
|
r46113 | /// A mercurial capability as not been implemented. | ||
Unimplemented, | ||||
|
r45592 | } | ||
|
r47163 | impl CommandError { | ||
|
r45592 | pub fn get_exit_code(&self) -> exitcode::ExitCode { | ||
match self { | ||||
|
r47163 | CommandError::RootNotFound(_) => exitcode::ABORT, | ||
CommandError::CurrentDirNotFound(_) => exitcode::ABORT, | ||||
CommandError::RequirementsError( | ||||
|
r46549 | RequirementsError::Unsupported { .. }, | ||
) => exitcode::UNIMPLEMENTED_COMMAND, | ||||
|
r47163 | CommandError::RequirementsError(_) => exitcode::ABORT, | ||
CommandError::StdoutError => exitcode::ABORT, | ||||
CommandError::StderrError => exitcode::ABORT, | ||||
CommandError::Abort(_) => exitcode::ABORT, | ||||
CommandError::Unimplemented => exitcode::UNIMPLEMENTED_COMMAND, | ||||
|
r45592 | } | ||
} | ||||
|
r45920 | |||
|
r47163 | /// Return the message corresponding to the error if any | ||
|
r45920 | pub fn get_error_message_bytes(&self) -> Option<Vec<u8>> { | ||
match self { | ||||
|
r47163 | CommandError::RootNotFound(path) => { | ||
|
r45920 | let bytes = get_bytes_from_path(path); | ||
|
r46598 | Some(format_bytes!( | ||
b"abort: no repository found in '{}' (.hg not found)!\n", | ||||
bytes.as_slice() | ||||
)) | ||||
|
r45920 | } | ||
|
r47163 | CommandError::CurrentDirNotFound(e) => Some(format_bytes!( | ||
|
r46598 | b"abort: error getting current working directory: {}\n", | ||
e.to_string().as_bytes(), | ||||
)), | ||||
|
r47163 | CommandError::RequirementsError(RequirementsError::Corrupted) => { | ||
Some( | ||||
"abort: .hg/requires is corrupted\n".as_bytes().to_owned(), | ||||
) | ||||
} | ||||
CommandError::Abort(message) => message.to_owned(), | ||||
|
r45920 | _ => None, | ||
} | ||||
} | ||||
|
r45592 | |||
/// Exist the process with the corresponding exit code. | ||||
|
r46010 | pub fn exit(&self) { | ||
|
r47163 | std::process::exit(self.get_exit_code()) | ||
|
r45592 | } | ||
} | ||||
impl From<UiError> for CommandError { | ||||
fn from(error: UiError) -> Self { | ||||
|
r47163 | match error { | ||
UiError::StdoutError(_) => CommandError::StdoutError, | ||||
UiError::StderrError(_) => CommandError::StderrError, | ||||
|
r45592 | } | ||
} | ||||
} | ||||
|
r45922 | |||
impl From<FindRootError> for CommandError { | ||||
fn from(err: FindRootError) -> Self { | ||||
|
r47163 | match err { | ||
FindRootError::RootNotFound(path) => { | ||||
CommandError::RootNotFound(path) | ||||
} | ||||
FindRootError::GetCurrentDirError(e) => { | ||||
CommandError::CurrentDirNotFound(e) | ||||
} | ||||
|
r45922 | } | ||
} | ||||
} | ||||
|
r47165 | |||
impl From<(DebugDataError, &str)> for CommandError { | ||||
fn from((err, rev): (DebugDataError, &str)) -> CommandError { | ||||
match err { | ||||
DebugDataError::IoError(err) => CommandError::Abort(Some( | ||||
utf8_to_local(&format!("abort: {}\n", err)).into(), | ||||
)), | ||||
DebugDataError::InvalidRevision => CommandError::Abort(Some( | ||||
utf8_to_local(&format!( | ||||
"abort: invalid revision identifier{}\n", | ||||
rev | ||||
)) | ||||
.into(), | ||||
)), | ||||
DebugDataError::AmbiguousPrefix => CommandError::Abort(Some( | ||||
utf8_to_local(&format!( | ||||
"abort: ambiguous revision identifier{}\n", | ||||
rev | ||||
)) | ||||
.into(), | ||||
)), | ||||
DebugDataError::UnsuportedRevlogVersion(version) => { | ||||
CommandError::Abort(Some( | ||||
utf8_to_local(&format!( | ||||
"abort: unsupported revlog version {}\n", | ||||
version | ||||
)) | ||||
.into(), | ||||
)) | ||||
} | ||||
DebugDataError::CorruptedRevlog => { | ||||
CommandError::Abort(Some("abort: corrupted revlog\n".into())) | ||||
} | ||||
DebugDataError::UnknowRevlogDataFormat(format) => { | ||||
CommandError::Abort(Some( | ||||
utf8_to_local(&format!( | ||||
"abort: unknow revlog dataformat {:?}\n", | ||||
format | ||||
)) | ||||
.into(), | ||||
)) | ||||
} | ||||
} | ||||
} | ||||
} | ||||
impl From<(ListRevTrackedFilesError, &str)> for CommandError { | ||||
fn from((err, rev): (ListRevTrackedFilesError, &str)) -> CommandError { | ||||
match err { | ||||
ListRevTrackedFilesError::IoError(err) => CommandError::Abort( | ||||
Some(utf8_to_local(&format!("abort: {}\n", err)).into()), | ||||
), | ||||
ListRevTrackedFilesError::InvalidRevision => { | ||||
CommandError::Abort(Some( | ||||
utf8_to_local(&format!( | ||||
"abort: invalid revision identifier {}\n", | ||||
rev | ||||
)) | ||||
.into(), | ||||
)) | ||||
} | ||||
ListRevTrackedFilesError::AmbiguousPrefix => { | ||||
CommandError::Abort(Some( | ||||
utf8_to_local(&format!( | ||||
"abort: ambiguous revision identifier {}\n", | ||||
rev | ||||
)) | ||||
.into(), | ||||
)) | ||||
} | ||||
ListRevTrackedFilesError::UnsuportedRevlogVersion(version) => { | ||||
CommandError::Abort(Some( | ||||
utf8_to_local(&format!( | ||||
"abort: unsupported revlog version {}\n", | ||||
version | ||||
)) | ||||
.into(), | ||||
)) | ||||
} | ||||
ListRevTrackedFilesError::CorruptedRevlog => { | ||||
CommandError::Abort(Some("abort: corrupted revlog\n".into())) | ||||
} | ||||
ListRevTrackedFilesError::UnknowRevlogDataFormat(format) => { | ||||
CommandError::Abort(Some( | ||||
utf8_to_local(&format!( | ||||
"abort: unknow revlog dataformat {:?}\n", | ||||
format | ||||
)) | ||||
.into(), | ||||
)) | ||||
} | ||||
} | ||||
} | ||||
} | ||||
impl From<(CatRevError, &str)> for CommandError { | ||||
fn from((err, rev): (CatRevError, &str)) -> CommandError { | ||||
match err { | ||||
CatRevError::IoError(err) => CommandError::Abort(Some( | ||||
utf8_to_local(&format!("abort: {}\n", err)).into(), | ||||
)), | ||||
CatRevError::InvalidRevision => CommandError::Abort(Some( | ||||
utf8_to_local(&format!( | ||||
"abort: invalid revision identifier {}\n", | ||||
rev | ||||
)) | ||||
.into(), | ||||
)), | ||||
CatRevError::AmbiguousPrefix => CommandError::Abort(Some( | ||||
utf8_to_local(&format!( | ||||
"abort: ambiguous revision identifier {}\n", | ||||
rev | ||||
)) | ||||
.into(), | ||||
)), | ||||
CatRevError::UnsuportedRevlogVersion(version) => { | ||||
CommandError::Abort(Some( | ||||
utf8_to_local(&format!( | ||||
"abort: unsupported revlog version {}\n", | ||||
version | ||||
)) | ||||
.into(), | ||||
)) | ||||
} | ||||
CatRevError::CorruptedRevlog => { | ||||
CommandError::Abort(Some("abort: corrupted revlog\n".into())) | ||||
} | ||||
CatRevError::UnknowRevlogDataFormat(format) => { | ||||
CommandError::Abort(Some( | ||||
utf8_to_local(&format!( | ||||
"abort: unknow revlog dataformat {:?}\n", | ||||
format | ||||
)) | ||||
.into(), | ||||
)) | ||||
} | ||||
} | ||||
} | ||||
} | ||||
impl From<ListDirstateTrackedFilesError> for CommandError { | ||||
fn from(err: ListDirstateTrackedFilesError) -> Self { | ||||
match err { | ||||
ListDirstateTrackedFilesError::IoError(err) => { | ||||
CommandError::Abort(Some( | ||||
utf8_to_local(&format!("abort: {}\n", err)).into(), | ||||
)) | ||||
} | ||||
ListDirstateTrackedFilesError::ParseError(_) => { | ||||
CommandError::Abort(Some( | ||||
// TODO find a better error message | ||||
b"abort: parse error\n".to_vec(), | ||||
)) | ||||
} | ||||
} | ||||
} | ||||
} | ||||