comparison rust/hg-core/src/errors.rs @ 47413:6e49769b7f97

rhg: add exit code to HgError::Abort() My previous attempts to have rhg end with correct exit code was more of bug hunting. I found cases which were failing and fixed them. But as one might expect, more tests started failing. Let's add exit code `HgError::Abort()` and make it users explicitly tell what exit code they want. Differential Revision: https://phab.mercurial-scm.org/D10838
author Pulkit Goyal <7895pulkit@gmail.com>
date Mon, 07 Jun 2021 17:27:49 +0530
parents bcdcb4423ae3
children cf5f8da2244c
comparison
equal deleted inserted replaced
47412:3237ed4dcda4 47413:6e49769b7f97
1 use crate::config::ConfigValueParseError; 1 use crate::config::ConfigValueParseError;
2 use crate::exit_codes;
2 use std::fmt; 3 use std::fmt;
3 4
4 /// Common error cases that can happen in many different APIs 5 /// Common error cases that can happen in many different APIs
5 #[derive(Debug, derive_more::From)] 6 #[derive(Debug, derive_more::From)]
6 pub enum HgError { 7 pub enum HgError {
25 /// machine-readable. 26 /// machine-readable.
26 UnsupportedFeature(String), 27 UnsupportedFeature(String),
27 28
28 /// Operation cannot proceed for some other reason. 29 /// Operation cannot proceed for some other reason.
29 /// 30 ///
30 /// The given string is a short explanation for users, not intended to be 31 /// The message is a short explanation for users, not intended to be
31 /// machine-readable. 32 /// machine-readable.
32 Abort(String), 33 Abort {
34 message: String,
35 detailed_exit_code: exit_codes::ExitCode,
36 },
33 37
34 /// A configuration value is not in the expected syntax. 38 /// A configuration value is not in the expected syntax.
35 /// 39 ///
36 /// These errors can happen in many places in the code because values are 40 /// These errors can happen in many places in the code because values are
37 /// parsed lazily as the file-level parser does not know the expected type 41 /// parsed lazily as the file-level parser does not know the expected type
67 } 71 }
68 72
69 pub fn unsupported(explanation: impl Into<String>) -> Self { 73 pub fn unsupported(explanation: impl Into<String>) -> Self {
70 HgError::UnsupportedFeature(explanation.into()) 74 HgError::UnsupportedFeature(explanation.into())
71 } 75 }
72 pub fn abort(explanation: impl Into<String>) -> Self { 76
73 HgError::Abort(explanation.into()) 77 pub fn abort(
78 explanation: impl Into<String>,
79 exit_code: exit_codes::ExitCode,
80 ) -> Self {
81 HgError::Abort {
82 message: explanation.into(),
83 detailed_exit_code: exit_code,
84 }
74 } 85 }
75 } 86 }
76 87
77 // TODO: use `DisplayBytes` instead to show non-Unicode filenames losslessly? 88 // TODO: use `DisplayBytes` instead to show non-Unicode filenames losslessly?
78 impl fmt::Display for HgError { 89 impl fmt::Display for HgError {
79 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 90 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
80 match self { 91 match self {
81 HgError::Abort(explanation) => write!(f, "{}", explanation), 92 HgError::Abort { message, .. } => write!(f, "{}", message),
82 HgError::IoError { error, context } => { 93 HgError::IoError { error, context } => {
83 write!(f, "abort: {}: {}", context, error) 94 write!(f, "abort: {}: {}", context, error)
84 } 95 }
85 HgError::CorruptedRepository(explanation) => { 96 HgError::CorruptedRepository(explanation) => {
86 write!(f, "abort: {}", explanation) 97 write!(f, "abort: {}", explanation)