Show More
@@ -81,6 +81,7 b' impl ConfigLayer {' | |||
|
81 | 81 | String::from_utf8_lossy(arg), |
|
82 | 82 | ), |
|
83 | 83 | CONFIG_PARSE_ERROR_ABORT, |
|
84 | None, | |
|
84 | 85 | ))? |
|
85 | 86 | } |
|
86 | 87 | } |
@@ -33,6 +33,7 b' pub enum HgError {' | |||
|
33 | 33 | Abort { |
|
34 | 34 | message: String, |
|
35 | 35 | detailed_exit_code: exit_codes::ExitCode, |
|
36 | hint: Option<String>, | |
|
36 | 37 | }, |
|
37 | 38 | |
|
38 | 39 | /// A configuration value is not in the expected syntax. |
@@ -82,10 +83,12 b' impl HgError {' | |||
|
82 | 83 | pub fn abort( |
|
83 | 84 | explanation: impl Into<String>, |
|
84 | 85 | exit_code: exit_codes::ExitCode, |
|
86 | hint: Option<String>, | |
|
85 | 87 | ) -> Self { |
|
86 | 88 | HgError::Abort { |
|
87 | 89 | message: explanation.into(), |
|
88 | 90 | detailed_exit_code: exit_code, |
|
91 | hint, | |
|
89 | 92 | } |
|
90 | 93 | } |
|
91 | 94 | } |
@@ -20,6 +20,7 b' pub enum CommandError {' | |||
|
20 | 20 | Abort { |
|
21 | 21 | message: Vec<u8>, |
|
22 | 22 | detailed_exit_code: exit_codes::ExitCode, |
|
23 | hint: Option<Vec<u8>>, | |
|
23 | 24 | }, |
|
24 | 25 | |
|
25 | 26 | /// Exit with a failure exit code but no message. |
@@ -50,6 +51,19 b' impl CommandError {' | |||
|
50 | 51 | // https://www.mercurial-scm.org/wiki/EncodingStrategy#Mixing_output |
|
51 | 52 | message: utf8_to_local(message.as_ref()).into(), |
|
52 | 53 | detailed_exit_code: detailed_exit_code, |
|
54 | hint: None, | |
|
55 | } | |
|
56 | } | |
|
57 | ||
|
58 | pub fn abort_with_exit_code_and_hint( | |
|
59 | message: impl AsRef<str>, | |
|
60 | detailed_exit_code: exit_codes::ExitCode, | |
|
61 | hint: Option<impl AsRef<str>>, | |
|
62 | ) -> Self { | |
|
63 | CommandError::Abort { | |
|
64 | message: utf8_to_local(message.as_ref()).into(), | |
|
65 | detailed_exit_code, | |
|
66 | hint: hint.map(|h| utf8_to_local(h.as_ref()).into()), | |
|
53 | 67 | } |
|
54 | 68 | } |
|
55 | 69 | |
@@ -62,6 +76,7 b' impl CommandError {' | |||
|
62 | 76 | CommandError::Abort { |
|
63 | 77 | message: message.as_ref().into(), |
|
64 | 78 | detailed_exit_code, |
|
79 | hint: None, | |
|
65 | 80 | } |
|
66 | 81 | } |
|
67 | 82 | |
@@ -92,9 +107,12 b' impl From<HgError> for CommandError {' | |||
|
92 | 107 | HgError::Abort { |
|
93 | 108 | message, |
|
94 | 109 | detailed_exit_code, |
|
95 |
|
|
|
96 |
|
|
|
97 |
|
|
|
110 | hint, | |
|
111 | } => CommandError::abort_with_exit_code_and_hint( | |
|
112 | message, | |
|
113 | detailed_exit_code, | |
|
114 | hint, | |
|
115 | ), | |
|
98 | 116 | _ => CommandError::abort(error.to_string()), |
|
99 | 117 | } |
|
100 | 118 | } |
@@ -121,13 +139,15 b' impl From<UiError> for CommandError {' | |||
|
121 | 139 | impl From<RepoError> for CommandError { |
|
122 | 140 | fn from(error: RepoError) -> Self { |
|
123 | 141 | match error { |
|
124 |
RepoError::NotFound { at } => |
|
|
125 |
|
|
|
126 | b"abort: repository {} not found", | |
|
127 | get_bytes_from_path(at) | |
|
128 | ), | |
|
129 | detailed_exit_code: exit_codes::ABORT, | |
|
130 | }, | |
|
142 | RepoError::NotFound { at } => { | |
|
143 | CommandError::abort_with_exit_code_bytes( | |
|
144 | format_bytes!( | |
|
145 | b"abort: repository {} not found", | |
|
146 | get_bytes_from_path(at) | |
|
147 | ), | |
|
148 | exit_codes::ABORT, | |
|
149 | ) | |
|
150 | } | |
|
131 | 151 | RepoError::ConfigParseError(error) => error.into(), |
|
132 | 152 | RepoError::Other(error) => error.into(), |
|
133 | 153 | } |
@@ -137,13 +157,13 b' impl From<RepoError> for CommandError {' | |||
|
137 | 157 | impl<'a> From<&'a NoRepoInCwdError> for CommandError { |
|
138 | 158 | fn from(error: &'a NoRepoInCwdError) -> Self { |
|
139 | 159 | let NoRepoInCwdError { cwd } = error; |
|
140 |
CommandError:: |
|
|
141 |
|
|
|
160 | CommandError::abort_with_exit_code_bytes( | |
|
161 | format_bytes!( | |
|
142 | 162 | b"abort: no repository found in '{}' (.hg not found)!", |
|
143 | 163 | get_bytes_from_path(cwd) |
|
144 | 164 | ), |
|
145 |
|
|
|
146 |
|
|
|
165 | exit_codes::ABORT, | |
|
166 | ) | |
|
147 | 167 | } |
|
148 | 168 | } |
|
149 | 169 | |
@@ -168,15 +188,15 b' impl From<ConfigParseError> for CommandE' | |||
|
168 | 188 | } else { |
|
169 | 189 | Vec::new() |
|
170 | 190 | }; |
|
171 |
CommandError:: |
|
|
172 |
|
|
|
191 | CommandError::abort_with_exit_code_bytes( | |
|
192 | format_bytes!( | |
|
173 | 193 | b"config error at {}{}: {}", |
|
174 | 194 | origin, |
|
175 | 195 | line_message, |
|
176 | 196 | message |
|
177 | 197 | ), |
|
178 |
|
|
|
179 |
|
|
|
198 | exit_codes::CONFIG_ERROR_ABORT, | |
|
199 | ) | |
|
180 | 200 | } |
|
181 | 201 | } |
|
182 | 202 |
@@ -372,8 +372,7 b' fn exit_code(' | |||
|
372 | 372 | match result { |
|
373 | 373 | Ok(()) => exit_codes::OK, |
|
374 | 374 | Err(CommandError::Abort { |
|
375 | message: _, | |
|
376 | detailed_exit_code, | |
|
375 | detailed_exit_code, .. | |
|
377 | 376 | }) => { |
|
378 | 377 | if use_detailed_exit_code { |
|
379 | 378 | *detailed_exit_code |
@@ -480,15 +479,15 b' fn exit_no_fallback(' | |||
|
480 | 479 | match &result { |
|
481 | 480 | Ok(_) => {} |
|
482 | 481 | Err(CommandError::Unsuccessful) => {} |
|
483 | Err(CommandError::Abort { | |
|
484 | message, | |
|
485 | detailed_exit_code: _, | |
|
486 | }) => { | |
|
482 | Err(CommandError::Abort { message, hint, .. }) => { | |
|
483 | // Ignore errors when writing to stderr, we’re already exiting | |
|
484 | // with failure code so there’s not much more we can do. | |
|
487 | 485 | if !message.is_empty() { |
|
488 | // Ignore errors when writing to stderr, we’re already exiting | |
|
489 | // with failure code so there’s not much more we can do. | |
|
490 | 486 | let _ = ui.write_stderr(&format_bytes!(b"{}\n", message)); |
|
491 | 487 | } |
|
488 | if let Some(hint) = hint { | |
|
489 | let _ = ui.write_stderr(&format_bytes!(b"({})\n", hint)); | |
|
490 | } | |
|
492 | 491 | } |
|
493 | 492 | Err(CommandError::UnsupportedFeature { message }) => { |
|
494 | 493 | match on_unsupported { |
General Comments 0
You need to be logged in to leave comments.
Login now