scs_server: include error source chain on internal errors

Summary:
Include the full error source chain on any internal errors.  This will improve
debugability when internal errors are encountered, as the outermost context
might not be enough to describe the origin of the error.

Detect when backtraces are disabled, and only include them on the error if a backtrace was captured.

Reviewed By: StanislavGlebik

Differential Revision: D19813785

fbshipit-source-id: c28ffc0c44050a82cb7050afa57e976f37962432
This commit is contained in:
Mark Thomas 2020-02-10 07:24:21 -08:00 committed by Facebook Github Bot
parent c88ad00fcf
commit 8869eafe44
2 changed files with 23 additions and 6 deletions

View File

@ -6,6 +6,7 @@
* directory of this source tree.
*/
use std::backtrace::BacktraceStatus;
use std::error::Error as StdError;
use mononoke_api::MononokeError;
@ -40,10 +41,26 @@ impl From<MononokeError> for ServiceError {
kind: thrift::RequestErrorKind::PERMISSION_DENIED,
reason: error.to_string(),
}),
MononokeError::InternalError(error) => Self::Internal(thrift::InternalError {
reason: error.to_string(),
backtrace: error.backtrace().map(ToString::to_string),
}),
MononokeError::InternalError(error) => {
let reason = error.to_string();
let backtrace = error
.backtrace()
.and_then(|backtrace| match backtrace.status() {
BacktraceStatus::Captured => Some(backtrace.to_string()),
_ => None,
});
let mut source_chain = Vec::new();
let mut error: &dyn StdError = &error;
while let Some(source) = error.source() {
source_chain.push(source.to_string());
error = source;
}
Self::Internal(thrift::InternalError {
reason,
backtrace,
source_chain,
})
}
}
}
}
@ -91,6 +108,7 @@ pub(crate) fn internal_error(error: impl ToString) -> thrift::InternalError {
thrift::InternalError {
reason: error.to_string(),
backtrace: None,
source_chain: Vec::new(),
}
}

View File

@ -70,8 +70,7 @@ impl SourceControlServiceImpl {
Ok(())
})
.compat()
.await
.map_err(errors::internal_error)?;
.await?;
Ok(thrift::FileChunk {
offset: params.offset,
file_size: metadata.total_size as i64,