1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
use crate::pdb_crate::Error as PDBError; use addr2line::object; use goblin::error::Error as GoblinError; use thiserror::Error; pub type Result<T> = std::result::Result<T, GetSymbolsError>; #[derive(Error, Debug)] pub enum GetSymbolsError { #[error("Unmatched breakpad_id: Expected {0}, but received {1}")] UnmatchedBreakpadId(String, String), #[error("No match in multi-arch binary, errors: {}", .0.iter().map(|e| format!("{}", e)).collect::<Vec<String>>().join(", "))] NoMatchMultiArch(Vec<GetSymbolsError>), #[error("pdb_crate error: {1} ({0})")] PDBError(&'static str, PDBError), #[error("Invalid input: {0}")] InvalidInputError(&'static str), #[error("goblin error: {0}")] GoblinError(#[from] GoblinError), #[error("MachOHeader parsing error: {0}")] MachOHeaderParseError(#[source] object::read::Error), #[error( "get_candidate_paths_for_binary_or_pdb helper callback for {0} {1} returned error: {2}" )] HelperErrorDuringGetCandidatePathsForBinaryOrPdb( String, String, #[source] Box<dyn std::error::Error + Send + Sync>, ), #[error("get_candidate_paths_for_pdb helper callback for {0} {1} returned error: {2}")] HelperErrorDuringGetCandidatePathsForPdb( String, String, #[source] Box<dyn std::error::Error + Send + Sync>, ), #[error("read_file helper callback for file {0} returned error: {1}")] HelperErrorDuringReadFile(String, #[source] Box<dyn std::error::Error + Send + Sync>), #[error("No candidate path for binary, for {0} {1}")] NoCandidatePathForBinary(String, String), #[error("The PE (Windows) binary at path {0} did not contain information about an associated PDB file")] NoDebugInfoInPeBinary(String), #[error("In the PE (Windows) binary at path {0}, the embedded path to the PDB file did not end with a nul byte.")] PdbPathDidntEndWithNul(String), #[error("Couldn't parse request: {0}")] ParseRequestErrorSerde(#[from] serde_json::error::Error), #[error("Malformed request JSON: {0}")] ParseRequestErrorContents(&'static str), } pub trait Context<T> { fn context(self, context_description: &'static str) -> Result<T>; } impl<T> Context<T> for std::result::Result<T, PDBError> { fn context(self, context_description: &'static str) -> Result<T> { self.map_err(|e| GetSymbolsError::PDBError(context_description, e)) } } impl From<PDBError> for GetSymbolsError { fn from(err: PDBError) -> GetSymbolsError { GetSymbolsError::PDBError("Unknown", err) } } impl GetSymbolsError { pub fn enum_as_string(&self) -> &'static str { match *self { GetSymbolsError::UnmatchedBreakpadId(_, _) => "UnmatchedBreakpadId", GetSymbolsError::NoMatchMultiArch(_) => "NoMatchMultiArch", GetSymbolsError::PDBError(_, _) => "PDBError", GetSymbolsError::InvalidInputError(_) => "InvalidInputError", GetSymbolsError::GoblinError(_) => "GoblinError", GetSymbolsError::MachOHeaderParseError(_) => "MachOHeaderParseError", GetSymbolsError::HelperErrorDuringGetCandidatePathsForBinaryOrPdb(_, _, _) => { "HelperErrorDuringGetCandidatePathsForBinaryOrPdb" } GetSymbolsError::HelperErrorDuringGetCandidatePathsForPdb(_, _, _) => { "HelperErrorDuringGetCandidatePathsForPdb" } GetSymbolsError::HelperErrorDuringReadFile(_, _) => "HelperErrorDuringReadFile", GetSymbolsError::NoCandidatePathForBinary(_, _) => "NoCandidatePathForBinary", GetSymbolsError::NoDebugInfoInPeBinary(_) => "NoDebugInfoInPeBinary", GetSymbolsError::PdbPathDidntEndWithNul(_) => "PdbPathDidntEndWithNul", GetSymbolsError::ParseRequestErrorSerde(_) => "ParseRequestErrorSerde", GetSymbolsError::ParseRequestErrorContents(_) => "ParseRequestErrorContents", } } }