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