diff options
| -rw-r--r-- | mullvad-daemon/src/bin/problem-report.rs | 62 |
1 files changed, 53 insertions, 9 deletions
diff --git a/mullvad-daemon/src/bin/problem-report.rs b/mullvad-daemon/src/bin/problem-report.rs index 06d0fe853a..2186be166b 100644 --- a/mullvad-daemon/src/bin/problem-report.rs +++ b/mullvad-daemon/src/bin/problem-report.rs @@ -192,25 +192,41 @@ fn collect_report( ) -> Result<()> { let mut problem_report = ProblemReport::new(redact_custom_strings); - problem_report.add_logs(logs_from_log_directory()?); + match logs_from_log_directory() { + Ok(logs) => problem_report.try_add_logs(logs), + Err(error) => problem_report.add_error("Failed to list logs in log directory", error), + } + problem_report.add_logs(extra_logs); write_problem_report(&output_path, problem_report) .chain_err(|| ErrorKind::WriteReportError(output_path.to_path_buf())) } -fn logs_from_log_directory() -> Result<impl Iterator<Item = PathBuf>> { +fn logs_from_log_directory() -> Result<impl Iterator<Item = Result<PathBuf>>> { let log_dir = &*LOG_DIRECTORY; - let dir_entries: Vec<_> = fs::read_dir(&log_dir) - .and_then(|entries| entries.collect()) - .chain_err(|| ErrorKind::LogDirError(log_dir.clone()))?; - let files = dir_entries.into_iter().map(|dir_entry| dir_entry.path()); + fs::read_dir(&log_dir) + .chain_err(|| ErrorKind::LogDirError(log_dir.clone())) + .map(|dir_entries| { + let log_extension = Some(OsStr::new("log")); - let log_extension = Some(OsStr::new("log")); - let log_files = files.filter(move |file| file.extension() == log_extension); + dir_entries.filter_map(move |dir_entry_result| match dir_entry_result { + Ok(dir_entry) => { + let path = dir_entry.path(); - Ok(log_files) + if path.extension() == log_extension { + Some(Ok(path)) + } else { + None + } + } + Err(cause) => Some(Err(Error::with_chain( + cause, + ErrorKind::LogDirError(log_dir.clone()), + ))), + }) + }) } fn send_problem_report(user_email: &str, user_message: &str, report_path: &Path) -> Result<()> { @@ -268,6 +284,23 @@ impl ProblemReport { } } + /// Tries to attach some file logs to this report. + /// + /// This method receives a result with an iterator of results of file paths. If any of the + /// results are errors, they are collected and displayed in the final report. + pub fn try_add_logs<I, P>(&mut self, paths: I) + where + I: IntoIterator<Item = Result<P>>, + P: AsRef<Path>, + { + for path_result in paths { + match path_result { + Ok(path) => self.add_log(path.as_ref()), + Err(error) => self.add_error("Error getting next log file", error), + } + } + } + /// Attach a file log to this report. This method adds the error chain instead of the log /// contents if an error occurs while reading the log file. pub fn add_log(&mut self, path: &Path) { @@ -280,6 +313,17 @@ impl ProblemReport { } } + /// Attach an error to the report. + pub fn add_error<S, E>(&mut self, message: S, error: E) + where + S: ToString, + E: ChainedError, + { + let redacted_error = self.redact(&error.display_chain().to_string()); + + self.logs.push((message.to_string(), redacted_error)); + } + fn redact(&self, input: &str) -> String { let out1 = Self::redact_account_number(input); let out2 = Self::redact_home_dir(&out1); |
