in ingester/lib/src/symbolicator/mod.rs [1017:1088]
fn load_file(
&self,
location: Self::FL,
) -> std::pin::Pin<
Box<
dyn samply_symbols::OptionallySendFuture<Output = FileAndPathHelperResult<Self::F>>
+ '_,
>,
> {
Box::pin(async move {
if !self
.loaded_files
.lock()
.unwrap()
.contains_key(&location.key)
{
let loaded = 'result: {
let _permit = self.downloads.acquire().await;
let mut errors = AggregateError::new();
match self
.load_breakpad_file(&location.key, &location.cache_entry)
.await
{
Ok(Some(loaded)) => break 'result loaded,
Ok(None) => (),
Err(e) => errors
.push(e.context(format!("failed to get breakpad file for {location}"))),
}
match self
.load_symsrv_file(&location.key, &location.cache_entry)
.await
{
Ok(Some(loaded)) => break 'result loaded,
Ok(None) => (),
Err(e) => errors
.push(e.context(format!("failed to get symsrv file for {location}"))),
}
// Important: `into_result` will not create an `anyhow::Error` out of the
// `NotFoundError` here, as there's a bug where an `anyhow::Error` converted to
// a `Box<std::error::Error>` can't be downcast (see
// https://github.com/dtolnay/anyhow/issues/379). We check for `NotFoundError`
// by downcasting, and this function has to return a `Box<std::error::Error>`,
// so this is a bit fragile.
return errors.into_result(Err(NotFoundError(location).into()));
};
let prev = self
.loaded_files
.lock()
.unwrap()
.insert(location.key.clone(), loaded);
assert!(
prev.is_none(),
"load_file should only be called with a particular location once"
);
}
let mapped = if !location.symindex {
self.get_mapped(&location.key)
} else {
self.get_breakpad_symindex_mapped(&location.key)
};
if let Some(mapped) = mapped {
Ok(Contents(mapped))
} else {
Err(format!("failed to load mapped file for {location}").into())
}
})
}