Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
58c87e2
worker: Include error causes in job failure logs
Turbo87 Sep 21, 2026
07e04f9
worker: Include error causes in index cloning failures
Turbo87 Sep 21, 2026
37cc894
fastly: Simplify `PurgeFailed` and log its cause chain
Turbo87 Sep 21, 2026
ae96a34
jobs/index_version_downloads_archive: Include CDN error causes
Turbo87 Sep 21, 2026
2dcab7e
jobs/dump_db: Include error causes in CDN warnings
Turbo87 Sep 21, 2026
3467228
jobs/rss: Include error causes in CDN warning
Turbo87 Sep 21, 2026
73e48d0
docs_rs: Include causes in configuration and rebuild error logs
Turbo87 Sep 21, 2026
354b455
jobs/typosquat: Include causes in notification failures
Turbo87 Sep 21, 2026
b457f46
github: Include causes in secret-scanning notification failures
Turbo87 Sep 21, 2026
8ef6cd0
trustpub: Include causes in configuration notification failures
Turbo87 Sep 21, 2026
98e6647
trustpub: Include causes in OIDC key retrieval failures
Turbo87 Sep 21, 2026
b5d48d7
metrics: Include causes in service collection failures
Turbo87 Sep 21, 2026
dfca68f
sentry: Include causes in configuration failures
Turbo87 Sep 21, 2026
baa70b5
controllers/token: Include causes in notification failures
Turbo87 Sep 21, 2026
63c5d1f
krate: Include causes in `trustpub_only` notification failures
Turbo87 Sep 21, 2026
03220fb
trustpub: Include causes in GitHub token decryption failures
Turbo87 Sep 21, 2026
b189f11
github: Include causes in internal API errors
Turbo87 Sep 21, 2026
8a3a52f
tarball: Include error causes in checker example
Turbo87 Sep 21, 2026
f4fdeb9
db: Preserve PostgreSQL connection error causes
Turbo87 Sep 21, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/crates_io_docs_rs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ impl RealDocsRsClient {
Ok(Some(url)) => url,
Ok(None) => Url::parse(DEFAULT_BASE_URL).unwrap(),
Err(err) => {
warn!("Failed to parse DOCS_RS_BASE_URL: {err}");
warn!("Failed to parse DOCS_RS_BASE_URL: {err:#}");
return None;
}
};
Expand Down
27 changes: 6 additions & 21 deletions crates/crates_io_fastly/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,8 @@ pub enum Error {
#[error("Invalid API token format")]
InvalidApiToken(#[from] InvalidHeaderValue),

#[error("Failed to `POST {url}`{}: {source}", status.map(|s| format!(" (status: {})", s)).unwrap_or_default())]
PurgeFailed {
url: String,
status: Option<reqwest::StatusCode>,
#[source]
source: reqwest::Error,
},
#[error("Failed to purge Fastly cache")]
PurgeFailed(#[source] reqwest::Error),
}

#[derive(Debug)]
Expand Down Expand Up @@ -115,11 +110,7 @@ impl Fastly {
.header("Fastly-Key", self.token_header_value()?)
.send()
.await
.map_err(|source| Error::PurgeFailed {
url: url.clone(),
status: None,
source,
})?;
.map_err(Error::PurgeFailed)?;

let status = response.status();

Expand All @@ -138,11 +129,7 @@ impl Fastly {
"invalidation request to Fastly failed"
);

Err(Error::PurgeFailed {
url,
status: Some(status),
source: error,
})
Err(Error::PurgeFailed(error))
}
}
}
Expand Down Expand Up @@ -267,10 +254,8 @@ mod tests {

std::assert_matches!(
result,
Err(Error::PurgeFailed {
status: Some(reqwest::StatusCode::SERVICE_UNAVAILABLE),
..
})
Err(Error::PurgeFailed(source))
if source.status() == Some(reqwest::StatusCode::SERVICE_UNAVAILABLE)
);
}
}
4 changes: 3 additions & 1 deletion crates/crates_io_tarball/examples/check_all_crates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,9 @@ async fn process_path(path: &Path, pb: &ProgressBar) {
pb.suspend(|| match result {
Ok(result) => debug!(%pkg_name, path = %path.display(), ?result),
Err(error) => {
warn!(%pkg_name, path = %path.display(), "Failed to process tarball: {error}")
// Convert to anyhow so `{error:#}` includes the source chain.
let error = anyhow::Error::new(error);
warn!(%pkg_name, path = %path.display(), "Failed to process tarball: {error:#}")
}
})
}
Expand Down
4 changes: 2 additions & 2 deletions crates/crates_io_worker/src/worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ impl<Context: Clone + Send + Sync + 'static> Worker<Context> {
}
}
Err(error) => {
error!("Failed to run job: {error}");
error!("Failed to run job: {error:#}");
sleep(self.poll_interval).await;
}
}
Expand Down Expand Up @@ -108,7 +108,7 @@ impl<Context: Clone + Send + Sync + 'static> Worker<Context> {
storage::delete_successful_job(conn, job_id).await?
}
Err(error) => {
warn!("Failed to run job: {error}");
warn!("Failed to run job: {error:#}");
storage::update_failed_job(conn, job_id).await;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/bin/crates-io/background_worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ pub fn run() -> anyhow::Result<()> {
let ctx = ctx.clone();
move || {
if let Err(err) = ctx.lock_index() {
warn!("Failed to clone index: {err}");
warn!("Failed to clone index: {err:#}");
};
}
});
Expand Down
4 changes: 2 additions & 2 deletions src/controllers/github/secret_scanning.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ async fn alert_revoke_token(
let result = send_trustpub_notification_emails(&actual_crate_ids, alert, ctx, conn).await;
if let Err(error) = result {
warn!(
"Failed to send trusted publishing token exposure notifications for crates {actual_crate_ids:?}: {error}",
"Failed to send trusted publishing token exposure notifications for crates {actual_crate_ids:?}: {error:#}",
);
}

Expand Down Expand Up @@ -209,7 +209,7 @@ async fn alert_revoke_token(
if let Err(error) = send_notification_email(&token, alert, ctx, conn).await {
warn!(
token_id = %token.id, user_id = %token.user_id,
"Failed to send email notification: {error}",
"Failed to send email notification: {error:#}",
)
}

Expand Down
2 changes: 1 addition & 1 deletion src/controllers/krate/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ async fn update_inner(
};

if let Err(err) = email.send(ctx, email_address).await {
warn!("Failed to send trustpub_only notification to {email_address}: {err}");
warn!("Failed to send trustpub_only notification to {email_address}: {err:#}");
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/controllers/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ pub async fn create_api_token(
// email should not cause an error response to be returned to the
// caller.
if let Err(e) = send_creation_email(&ctx.emails, &recipient, context).await {
error!("Failed to send token creation email: {e}")
error!("Failed to send token creation email: {e:#}")
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/controllers/trustpub/github_configs/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ pub async fn create_trustpub_github_config(
};
let gh_auth = encryption.decrypt(gh_auth).map_err(|err| {
let login = &auth_user.gh_login;
warn!("Failed to decrypt GitHub token for user {login}: {err}");
warn!("Failed to decrypt GitHub token for user {login}: {err:#}");
server_error("Internal server error")
})?;
let gh_auth = GitHubAuth::bearer(gh_auth);
Expand Down Expand Up @@ -145,7 +145,7 @@ pub async fn create_trustpub_github_config(
};

if let Err(err) = send_notification_email(&ctx, email_address, context).await {
warn!("Failed to send trusted publishing notification to {email_address}: {err}");
warn!("Failed to send trusted publishing notification to {email_address}: {err:#}");
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/controllers/trustpub/github_configs/delete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ pub async fn delete_trustpub_github_config(
};

if let Err(err) = send_notification_email(&ctx, email_address, context).await {
warn!("Failed to send trusted publishing notification to {email_address}: {err}");
warn!("Failed to send trusted publishing notification to {email_address}: {err:#}");
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/controllers/trustpub/gitlab_configs/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ pub async fn create_trustpub_gitlab_config(
};

if let Err(err) = send_notification_email(&ctx, email_address, context).await {
warn!("Failed to send trusted publishing notification to {email_address}: {err}");
warn!("Failed to send trusted publishing notification to {email_address}: {err:#}");
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/controllers/trustpub/gitlab_configs/delete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ pub async fn delete_trustpub_gitlab_config(
};

if let Err(err) = send_notification_email(&ctx, email_address, context).await {
warn!("Failed to send trusted publishing notification to {email_address}: {err}");
warn!("Failed to send trusted publishing notification to {email_address}: {err:#}");
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/controllers/trustpub/tokens/exchange/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ pub async fn exchange_trustpub_token(
return Err(bad_request("Invalid JWT key ID"));
}
Err(err) => {
warn!("Failed to load OIDC key set: {err}");
warn!("Failed to load OIDC key set: {err:#}");
return Err(server_error("Failed to load OIDC key set"));
}
};
Expand Down
6 changes: 5 additions & 1 deletion src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,11 @@ async fn establish_async_connection(

let connector = MakeTlsConnector::new(connector);
let result = tokio_postgres::connect(url, connector).await;
let (client, conn) = result.map_err(|err| BadConnection(err.to_string()))?;
let (client, conn) = result.map_err(|error| {
// Convert to anyhow so `{error:#}` includes the source chain.
let error = anyhow::Error::new(error);
BadConnection(format!("{error:#}"))
})?;
AsyncPgConnection::try_from_client_and_connection(client, conn).await
}

Expand Down
2 changes: 1 addition & 1 deletion src/metrics/collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pub fn spawn(deadpool: Pool<AsyncPgConnection>, metrics: WorkerMetrics) {

loop {
if let Err(error) = record(&deadpool, &metrics, &mut observed_queues).await {
warn!("Failed to record service metrics: {error}");
warn!("Failed to record service metrics: {error:#}");
}

tokio::time::sleep(COLLECT_INTERVAL).await;
Expand Down
2 changes: 1 addition & 1 deletion src/sentry/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub fn init() -> Option<ClientInitGuard> {
let config = match SentryConfig::from_environment() {
Ok(config) => config,
Err(error) => {
warn!("Failed to read Sentry configuration from environment: {error}");
warn!("Failed to read Sentry configuration from environment: {error:#}");
return None;
}
};
Expand Down
2 changes: 1 addition & 1 deletion src/util/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ impl From<GitHubError> for BoxedAppError {
GitHub org memberships.",
),
GitHubError::NotFound(_) => not_found(),
_ => internal(format!("didn't get a 200 result from github: {error}")),
_ => internal(format!("didn't get a 200 result from github: {error:#}")),
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/worker/jobs/docs_rs_queue_rebuild.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ impl BackgroundJob for DocsRsQueueRebuild {
error!(
name = self.name,
version = self.version,
"couldn't queue docs rebuild. won't retry: {err}"
"couldn't queue docs rebuild. won't retry: {err:#}"
);
Ok(())
}
Expand Down
4 changes: 2 additions & 2 deletions src/worker/jobs/dump_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ impl BackgroundJob for DumpDb {
let dist = CloudFrontDistribution::Static;

if let Err(error) = ctx.invalidate_cdns(&conn, dist, &tar_key.cdn_path()).await {
warn!("Failed to invalidate CDN caches: {error}");
warn!("Failed to invalidate CDN caches: {error:#}");
}

info!("Uploading zip file…");
Expand All @@ -88,7 +88,7 @@ impl BackgroundJob for DumpDb {

info!("Invalidating CDN caches…");
if let Err(error) = ctx.invalidate_cdns(&conn, dist, &zip_key.cdn_path()).await {
warn!("Failed to invalidate CDN caches: {error}");
warn!("Failed to invalidate CDN caches: {error:#}");
}

Ok(())
Expand Down
4 changes: 3 additions & 1 deletion src/worker/jobs/generate_og_image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,9 @@ impl BackgroundJob for GenerateOgImage {
&& let Some(cdn_domain) = &ctx.config.storage.cdn_prefix
&& let Err(error) = fastly.purge_both_domains(cdn_domain, &og_image_path).await
{
warn!("Failed to invalidate Fastly CDN for {crate_name}: {error}");
// Convert to anyhow so `{error:#}` includes the source chain.
let error = anyhow::Error::new(error);
warn!("Failed to invalidate Fastly CDN for {crate_name}: {error:#}");
}

info!("CDN invalidation completed for crate {crate_name}");
Expand Down
4 changes: 3 additions & 1 deletion src/worker/jobs/index/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,9 +202,11 @@ impl BackgroundJob for SyncToSparseIndex {

for domain in domains {
if let Err(error) = fastly.purge(&domain, &path).await {
// Convert to anyhow so `{error:#}` includes the source chain.
let error = anyhow::Error::new(error);
warn!(
domain,
path, "Failed to invalidate sparse index on Fastly: {error}"
path, "Failed to invalidate sparse index on Fastly: {error:#}"
);
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/worker/jobs/index_version_downloads_archive/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,12 @@ impl BackgroundJob for IndexVersionDownloadsArchive {

let result = ctx.invalidate_cdns(&conn, dist, INDEX_PATH).await;
if let Err(error) = result {
warn!("Failed to invalidate CDN caches: {error}");
warn!("Failed to invalidate CDN caches: {error:#}");
}

let result = ctx.invalidate_cdns(&conn, dist, INDEX_JSON_PATH);
if let Err(error) = result.await {
warn!("Failed to invalidate CDN caches: {error}");
warn!("Failed to invalidate CDN caches: {error:#}");
}

info!("CDN caches invalidated");
Expand Down
2 changes: 1 addition & 1 deletion src/worker/jobs/rss/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ async fn publish_channel(

let dist = CloudFrontDistribution::Static;
if let Err(error) = ctx.invalidate_cdns(conn, dist, path.as_ref()).await {
warn!("Failed to invalidate CDN caches: {error}");
warn!("Failed to invalidate CDN caches: {error:#}");
}

Ok(())
Expand Down
2 changes: 1 addition & 1 deletion src/worker/jobs/typosquat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ async fn check(
{
error!(
?recipient,
"Failed to send possible typosquat notification: {error}"
"Failed to send possible typosquat notification: {error:#}"
);
}
}
Expand Down