Repository: cloudflare/daphne
Pull request #393 (2023-09-20 11:16:44)

Provide more control over display implementation when logging a fatal error


Patch:
diff --git a/daphne/src/error/mod.rs b/daphne/src/error/mod.rs
index b7a9c6c..be9a644 100644
--- a/daphne/src/error/mod.rs
+++ b/daphne/src/error/mod.rs
@@ -86,7 +86,7 @@ impl Debug for FatalDapError {
 ///
 /// let some_id = 1;
 /// let e = Error::new(ErrorKind::Other, "the error");
-/// fatal_error!(err = e, id = %some_id, "operation failed");
+/// fatal_error!(err = ?e, id = %some_id, "operation failed");
 /// ```
 ///
 /// # Note
@@ -94,17 +94,49 @@ impl Debug for FatalDapError {
 /// macro, pass a string only when there is no error value you can use.
 #[macro_export]
 macro_rules! fatal_error {
+    (err = ?$e:expr) => {
+        $crate::__fatal_error_impl!(@@ err = ?$e)
+    };
+    (err = %$e:expr) => {
+        $crate::__fatal_error_impl!(@@ err = %$e)
+    };
     (err = $e:expr) => {
-        $crate::fatal_error!(@@@ err = $e)
+        $crate::__fatal_error_impl!(@@ err = $e)
+    };
+    (err = ?$e:expr, $($rest:tt)*) => {
+        $crate::__fatal_error_impl!(@@ err = ?$e, $($rest)*)
+    };
+    (err = %$e:expr, $($rest:tt)*) => {
+        $crate::__fatal_error_impl!(@@ err = %$e, $($rest)*)
     };
     (err = $e:expr, $($rest:tt)*) => {
-        $crate::fatal_error!(@@@ err = $e, $($rest)*)
+        $crate::__fatal_error_impl!(@@ err = $e, $($rest)*)
     };
-    (@@@ err = $e:expr $(, $($rest:tt)*)?) => {{
+
+}
+
+#[macro_export]
+#[doc(hidden)]
+macro_rules! __fatal_error_impl {
+    (@@ err = ?$e:expr $(, $($rest:tt)*)?) => {{
         let error = &$e;
         ::tracing::error!(?error, $($($rest)*)*);
+        $crate::__fatal_error_impl!(@@@ error)
+    }};
+    (@@ err = %$e:expr $(, $($rest:tt)*)?) => {{
+        let error = &$e;
+        ::tracing::error!(%error, $($($rest)*)*);
+        $crate::__fatal_error_impl!(@@@ error)
+    }};
+    (@@ err = $e:expr $(, $($rest:tt)*)?) => {{
+        let error = &$e;
+        ::tracing::error!(error, $($($rest)*)*);
+        $crate::__fatal_error_impl!(@@@ error)
+    }};
+    (@@@ $error:expr) => {{
+        let error = $error;
         $crate::error::DapError::Fatal(
             $crate::error::FatalDapError::__use_the_macro(::std::format!("{error}"))
         )
-    }};
+    }}
 }
diff --git a/daphne/src/lib.rs b/daphne/src/lib.rs
index 8791724..967a97f 100644
--- a/daphne/src/lib.rs
+++ b/daphne/src/lib.rs
@@ -537,19 +537,19 @@ impl DapAggregateShare {
                 self.data = Some(data);
             }
             (Some(VdafAggregateShare::Field64(left)), Some(VdafAggregateShare::Field64(right))) => {
-                left.merge(&right).map_err(|e| fatal_error!(err = e))?;
+                left.merge(&right).map_err(|e| fatal_error!(err = ?e))?;
             }
             (
                 Some(VdafAggregateShare::Field128(left)),
                 Some(VdafAggregateShare::Field128(right)),
             ) => {
-                left.merge(&right).map_err(|e| fatal_error!(err = e))?;
+                left.merge(&right).map_err(|e| fatal_error!(err = ?e))?;
             }
             (
                 Some(VdafAggregateShare::FieldPrio2(left)),
                 Some(VdafAggregateShare::FieldPrio2(right)),
             ) => {
-                left.merge(&right).map_err(|e| fatal_error!(err = e))?;
+                left.merge(&right).map_err(|e| fatal_error!(err = ?e))?;
             }
 
             _ => return Err(fatal_error!(err = "invalid aggregate share merge")),
diff --git a/daphne/src/metrics.rs b/daphne/src/metrics.rs
index 45ce3e5..8229cae 100644
--- a/daphne/src/metrics.rs
+++ b/daphne/src/metrics.rs
@@ -40,7 +40,7 @@ impl DaphneMetrics {
             &["host", "type"],
             registry
         )
-        .map_err(|e| fatal_error!(err = e, "failed to regsiter inbound_request_counter"))?;
+        .map_err(|e| fatal_error!(err = ?e, "failed to regsiter inbound_request_counter"))?;
 
         let report_counter = register_int_counter_vec_with_registry!(
             format!("{front}report_counter"),
@@ -48,7 +48,7 @@ impl DaphneMetrics {
             &["host", "status"],
             registry
         )
-        .map_err(|e| fatal_error!(err = e, "failed to register report_counter"))?;
+        .map_err(|e| fatal_error!(err = ?e, "failed to register report_counter"))?;
 
         let aggregation_job_batch_size_histogram = register_histogram_vec_with_registry!(
             format!("{front}aggregation_job_batch_size"),
@@ -58,7 +58,7 @@ impl DaphneMetrics {
                 .expect("this shouldn't panic for these hardcoded values"), // <250, <500, ... <1500, +Inf
             registry
         )
-        .map_err(|e| fatal_error!(err = e, "failed to register aggregation_job_batch_size"))?;
+        .map_err(|e| fatal_error!(err = ?e, "failed to register aggregation_job_batch_size"))?;
 
         let aggregation_job_counter = register_int_counter_vec_with_registry!(
             format!("{front}aggregation_job_counter"),
@@ -66,7 +66,7 @@ impl DaphneMetrics {
             &["host", "status"],
             registry
         )
-        .map_err(|e| fatal_error!(err = e, "failed to register aggregation_job_counter"))?;
+        .map_err(|e| fatal_error!(err = ?e, "failed to register aggregation_job_counter"))?;
 
         Ok(Self {
             inbound_request_counter,
diff --git a/daphne/src/roles/leader.rs b/daphne/src/roles/leader.rs
index 1811b49..823ef98 100644
--- a/daphne/src/roles/leader.rs
+++ b/daphne/src/roles/leader.rs
@@ -54,7 +54,7 @@ async fn leader_send_http_request<S>(
     let url = task_config
         .helper_url
         .join(path)
-        .map_err(|e| fatal_error!(err = e))?;
+        .map_err(|e| fatal_error!(err = ?e))?;
 
     let req = DapRequest {
         version: task_config.version,
diff --git a/daphne_worker/src/config.rs b/daphne_worker/src/config.rs
index e7ceb6b..f739436 100644
--- a/daphne_worker/src/config.rs
+++ b/daphne_worker/src/config.rs
@@ -788,7 +788,7 @@ impl<'srv> DaphneWorker<'srv> {
     {
         self.get_task_config(Cow::Borrowed(task_id))
             .await
-            .map_err(|e| fatal_error!(err = e, "getting task config"))?
+            .map_err(|e| fatal_error!(err = ?e, "getting task config"))?
             .ok_or(DapError::Abort(DapAbort::UnrecognizedTask))
     }
 
@@ -797,17 +797,17 @@ impl<'srv> DaphneWorker<'srv> {
     /// TODO(cjpatton) Gate this to non-prod deployments. (Prod should do migration.)
     pub(crate) async fn internal_delete_all(&self) -> std::result::Result<(), DapError> {
         // Clear KV storage.
-        let kv_store = self.kv().map_err(|e| fatal_error!(err = e))?;
+        let kv_store = self.kv().map_err(|e| fatal_error!(err = ?e))?;
         let kv_task = async {
             for kv_key in kv_store
                 .list()
                 .execute()
                 .await
-                .map_err(|e| fatal_error!(err = e, "failed to list all keys from kv"))?
+                .map_err(|e| fatal_error!(err = ?e, "failed to list all keys from kv"))?
                 .keys
             {
                 kv_store.delete(kv_key.name.as_str()).await.map_err(
-                    |e| fatal_error!(err = e, name = %kv_key.name, "failed to delete key from kv"),
+                    |e| fatal_error!(err = ?e, name = %kv_key.name, "failed to delete key from kv"),
                 )?;
                 trace!("deleted KV item {}", kv_key.name);
             }
@@ -824,7 +824,7 @@ impl<'srv> DaphneWorker<'srv> {
                 "garbage_collector".to_string(),
                 &(),
             )
-            .map_err(|e| fatal_error!(err = e));
+            .map_err(|e| fatal_error!(err = ?e));
 
         futures::try_join!(kv_task, future_delete_durable)?;
 
@@ -853,7 +853,7 @@ impl<'srv> DaphneWorker<'srv> {
                 durable_name_task(&task_config.as_ref().version, &task_id.to_hex()),
             )
             .await
-            .map_err(|e| fatal_error!(err = e))?;
+            .map_err(|e| fatal_error!(err = ?e))?;
 
         match res {
             LeaderBatchQueueResult::Ok(batch_id) => Ok(batch_id),
@@ -1192,14 +1192,14 @@ impl<'srv> DaphneWorker<'srv> {
         headers.insert(
             reqwest_wasm::header::CONTENT_TYPE,
             reqwest_wasm::header::HeaderValue::from_str(content_type)
-                .map_err(|e| fatal_error!(err = e, "failed to construct content-type header"))?,
+                .map_err(|e| fatal_error!(err = ?e, "failed to construct content-type header"))?,
         );
 
         if let Some(bearer_token) = req.sender_auth.and_then(|auth| auth.bearer_token) {
             headers.insert(
                 reqwest_wasm::header::HeaderName::from_static("dap-auth-token"),
                 reqwest_wasm::header::HeaderValue::from_str(bearer_token.as_ref()).map_err(
-                    |e| fatal_error!(err = e, "failed to construct dap-auth-token header"),
+                    |e| fatal_error!(err = ?e, "failed to construct dap-auth-token header"),
                 )?,
             );
         }
@@ -1217,7 +1217,7 @@ impl<'srv> DaphneWorker<'srv> {
         let reqwest_resp = reqwest_req
             .send()
             .await
-            .map_err(|e| fatal_error!(err = e))?;
+            .map_err(|e| fatal_error!(err = ?e))?;
         let end = Date::now().as_millis();
         info!("request to {} completed in {}ms", url, end - start);
         let status = reqwest_resp.status();
@@ -1228,13 +1228,13 @@ impl<'srv> DaphneWorker<'srv> {
                 .get(reqwest_wasm::header::CONTENT_TYPE)
                 .ok_or_else(|| fatal_error!(err = INT_ERR_PEER_RESP_MISSING_MEDIA_TYPE))?
                 .to_str()
-                .map_err(|e| fatal_error!(err = e))?;
+                .map_err(|e| fatal_error!(err = ?e))?;
             let media_type = DapMediaType::from_str_for_version(req.version, Some(content_type));
 
             let payload = reqwest_resp
                 .bytes()
                 .await
-                .map_err(|e| fatal_error!(err = e))?
+                .map_err(|e| fatal_error!(err = ?e))?
                 .to_vec();
 
             Ok(DapResponse {
@@ -1255,7 +1255,7 @@ impl<'srv> DaphneWorker<'srv> {
                             reqwest_resp
                                 .text()
                                 .await
-                                .map_err(|e| fatal_error!(err = e))?
+                                .map_err(|e| fatal_error!(err = ?e))?
                         );
                     }
                 }
diff --git a/daphne_worker/src/dap.rs b/daphne_worker/src/dap.rs
index d0ffe1a..7a13a96 100644
--- a/daphne_worker/src/dap.rs
+++ b/daphne_worker/src/dap.rs
@@ -113,7 +113,7 @@ impl<'srv> HpkeDecrypter for DaphneWorker<'srv> {
                 .map(|receiver| receiver.config.clone())
         })
         .await
-        .map_err(|e| fatal_error!(err = e, "failed to get list of hpke key configs in kv"))?
+        .map_err(|e| fatal_error!(err = ?e, "failed to get list of hpke key configs in kv"))?
         .ok_or_else(|| fatal_error!(err = "there are no hpke configs in kv!!", %version))
     }
 
@@ -131,7 +131,7 @@ impl<'srv> HpkeDecrypter for DaphneWorker<'srv> {
                     .map(|_| ())
             })
             .await
-            .map_err(|e| fatal_error!(err = e))?
+            .map_err(|e| fatal_error!(err = ?e))?
             .is_some())
     }
 
@@ -150,7 +150,7 @@ impl<'srv> HpkeDecrypter for DaphneWorker<'srv> {
                 .map(|receiver| receiver.decrypt(info, aad, &ciphertext.enc, &ciphertext.payload))
         })
         .await
-        .map_err(|e| fatal_error!(err = e))?
+        .map_err(|e| fatal_error!(err = ?e))?
         .ok_or_else(|| DapError::Transition(TransitionFailure::HpkeUnknownConfigId))?
     }
 }
@@ -176,7 +176,7 @@ impl<'srv> BearerTokenProvider for DaphneWorker<'srv> {
 
         self.get_leader_bearer_token(task_id)
             .await
-            .map_err(|e| fatal_error!(err = e))
+            .map_err(|e| fatal_error!(err = ?e))
     }
 
     async fn get_collector_bearer_token_for<'s>(
@@ -199,7 +199,7 @@ impl<'srv> BearerTokenProvider for DaphneWorker<'srv> {
 
         self.get_collector_bearer_token(task_id)
             .await
-            .map_err(|e| fatal_error!(err = e))
+            .map_err(|e| fatal_error!(err = ?e))
     }
 }
 
@@ -291,7 +291,7 @@ impl DapReportInitializer for DaphneWorker<'_> {
         let reports_processed_responses: Vec<ReportsProcessedResp> =
             try_join_all(reports_processed_requests)
                 .await
-                .map_err(|e| fatal_error!(err = e))?;
+                .map_err(|e| fatal_error!(err = ?e))?;
 
         // Flatten the responses from ReportsProcessed into a hash map.
         let mut initialized_reports = HashMap::new();
@@ -313,7 +313,7 @@ impl DapReportInitializer for DaphneWorker<'_> {
         }
         let agg_store_responses: Vec<bool> = try_join_all(agg_store_requests)
             .await
-            .map_err(|e| fatal_error!(err = e))?;
+            .map_err(|e| fatal_error!(err = ?e))?;
 
         // Reject reports that have been collected.
         for (bucket, collected) in agg_store_request_bucket
@@ -496,7 +496,7 @@ impl<'srv> DapAggregator<DaphneWorkerAuth> for DaphneWorker<'srv> {
                 .isolate_state()
                 .tasks
                 .write()
-                .map_err(|e| fatal_error!(err = e, "failed to lock tasks for writing"))?;
+                .map_err(|e| fatal_error!(err = ?e, "failed to lock tasks for writing"))?;
             guarded_tasks.insert(task_id.clone(), task_config);
 
             if let Some(ref leader_bearer_token) = taskprov.leader_auth.bearer_token {
@@ -505,7 +505,7 @@ impl<'srv> DapAggregator<DaphneWorkerAuth> for DaphneWorker<'srv> {
                     .leader_bearer_tokens
                     .write()
                     .map_err(|e| {
-                        fatal_error!(err = e, "failed to lock leader_bearer_tokens for writing")
+                        fatal_error!(err = ?e, "failed to lock leader_bearer_tokens for writing")
                     })?;
                 guarded_leader_bearer_tokens.insert(task_id.clone(), leader_bearer_token.clone());
             }
@@ -513,12 +513,12 @@ impl<'srv> DapAggregator<DaphneWorkerAuth> for DaphneWorker<'srv> {
             // Write the task config through to KV.
             self.set_task_config(task_id, &task_config)
                 .await
-                .map_err(|e| fatal_error!(err = e))?;
+                .map_err(|e| fatal_error!(err = ?e))?;
 
             if let Some(ref leader_bearer_token) = taskprov.leader_auth.bearer_token {
                 self.set_leader_bearer_token(task_id, leader_bearer_token)
                     .await
-                    .map_err(|e| fatal_error!(err = e))?;
+                    .map_err(|e| fatal_error!(err = ?e))?;
             }
         }
 
@@ -531,7 +531,7 @@ impl<'srv> DapAggregator<DaphneWorkerAuth> for DaphneWorker<'srv> {
     ) -> std::result::Result<Option<Self::WrappedDapTaskConfig<'req>>, DapError> {
         self.get_task_config(task_id)
             .await
-            .map_err(|e| fatal_error!(err = e))
+            .map_err(|e| fatal_error!(err = ?e))
     }
 
     fn get_current_time(&self) -> u64 {
@@ -562,7 +562,7 @@ impl<'srv> DapAggregator<DaphneWorkerAuth> for DaphneWorker<'srv> {
 
         let responses: Vec<bool> = try_join_all(requests)
             .await
-            .map_err(|e| fatal_error!(err = e))?;
+            .map_err(|e| fatal_error!(err = ?e))?;
 
         for collected in responses {
             if collected {
@@ -593,7 +593,7 @@ impl<'srv> DapAggregator<DaphneWorkerAuth> for DaphneWorker<'srv> {
                 ),
             )
             .await
-            .map_err(|e| fatal_error!(err = e))?;
+            .map_err(|e| fatal_error!(err = ?e))?;
 
         Ok(!agg_share.empty())
     }
@@ -647,7 +647,7 @@ impl<'srv> DapAggregator<DaphneWorkerAuth> for DaphneWorker<'srv> {
             },
         ))
         .await
-        .map_err(|e| fatal_error!(err = e))?
+        .map_err(|e| fatal_error!(err = ?e))?
         .into_iter()
         .flatten()
         .collect::<HashSet<ReportId>>();
@@ -674,7 +674,7 @@ impl<'srv> DapAggregator<DaphneWorkerAuth> for DaphneWorker<'srv> {
             },
         ))
         .await
-        .map_err(|e| fatal_error!(err = e))?;
+        .map_err(|e| fatal_error!(err = ?e))?;
 
         Ok(replayed)
     }
@@ -699,7 +699,7 @@ impl<'srv> DapAggregator<DaphneWorkerAuth> for DaphneWorker<'srv> {
         }
         let responses: Vec<DapAggregateShare> = try_join_all(requests)
             .await
-            .map_err(|e| fatal_error!(err = e))?;
+            .map_err(|e| fatal_error!(err = ?e))?;
         let mut agg_share = DapAggregateShare::default();
         for agg_share_delta in responses {
             agg_share.merge(agg_share_delta)?;
@@ -730,7 +730,7 @@ impl<'srv> DapAggregator<DaphneWorkerAuth> for DaphneWorker<'srv> {
 
         try_join_all(requests)
             .await
-            .map_err(|e| fatal_error!(err = e))?;
+            .map_err(|e| fatal_error!(err = ?e))?;
         Ok(())
     }
 
@@ -778,7 +778,7 @@ impl<'srv> DapLeader<DaphneWorkerAuth> for DaphneWorker<'srv> {
                 &pending_report,
             )
             .await
-            .map_err(|e| fatal_error!(err = e))?;
+            .map_err(|e| fatal_error!(err = ?e))?;
 
         match res {
             ReportsPendingResult::Ok => Ok(()),
@@ -812,7 +812,7 @@ impl<'srv> DapLeader<DaphneWorkerAuth> for DaphneWorker<'srv> {
                 &report_sel.max_agg_jobs,
             )
             .await
-            .map_err(|e| fatal_error!(err = e))?;
+            .map_err(|e| fatal_error!(err = ?e))?;
 
         // Drain at most `report_sel.max_reports` from each ReportsPending instance and group them
         // by task.
@@ -828,7 +828,7 @@ impl<'srv> DapLeader<DaphneWorkerAuth> for DaphneWorker<'srv> {
                     &report_sel.max_reports,
                 )
                 .await
-                .map_err(|e| fatal_error!(err = e))?;
+                .map_err(|e| fatal_error!(err = ?e))?;
 
             for pending_report in reports_from_durable {
                 let report_bytes = hex::decode(&pending_report.report_hex)
@@ -855,7 +855,7 @@ impl<'srv> DapLeader<DaphneWorkerAuth> for DaphneWorker<'srv> {
             let task_config = self
                 .get_task_config(Cow::Owned(task_id))
                 .await
-                .map_err(|e| fatal_error!(err = e))?
+                .map_err(|e| fatal_error!(err = ?e))?
                 .ok_or_else(|| fatal_error!(err = "unrecognized task"))?;
             let task_id_hex = task_config.key().to_hex();
             let reports_per_part = reports_per_task_part
@@ -875,7 +875,7 @@ impl<'srv> DapLeader<DaphneWorkerAuth> for DaphneWorker<'srv> {
                             &(task_config.as_ref().min_batch_size, num_unassigned),
                         )
                         .await
-                        .map_err(|e| fatal_error!(err = e))?;
+                        .map_err(|e| fatal_error!(err = ?e))?;
                     for batch_count in batch_assignments.into_iter() {
                         let BatchCount {
                             batch_id,
@@ -934,7 +934,7 @@ impl<'srv> DapLeader<DaphneWorkerAuth> for DaphneWorker<'srv> {
                 &collect_queue_req,
             )
             .await
-            .map_err(|e| fatal_error!(err = e))?;
+            .map_err(|e| fatal_error!(err = ?e))?;
         debug!("assigned collect_id {collect_id}");
 
         let url = task_config.as_ref().leader_url.clone();
@@ -946,7 +946,7 @@ impl<'srv> DapLeader<DaphneWorkerAuth> for DaphneWorker<'srv> {
                 task_id.to_base64url(),
                 collect_id.to_base64url(),
             ))
-            .map_err(|e| fatal_error!(err = e))?;
+            .map_err(|e| fatal_error!(err = ?e))?;
 
         Ok(collect_uri)
     }
@@ -965,7 +965,7 @@ impl<'srv> DapLeader<DaphneWorkerAuth> for DaphneWorker<'srv> {
                 (&task_id, &collect_id),
             )
             .await
-            .map_err(|e| fatal_error!(err = e))?;
+            .map_err(|e| fatal_error!(err = ?e))?;
         Ok(res)
     }
 
@@ -980,7 +980,7 @@ impl<'srv> DapLeader<DaphneWorkerAuth> for DaphneWorker<'srv> {
                 durable_name_queue(0),
             )
             .await
-            .map_err(|e| fatal_error!(err = e))?;
+            .map_err(|e| fatal_error!(err = ?e))?;
         Ok(res)
     }
 
@@ -1003,7 +1003,7 @@ impl<'srv> DapLeader<DaphneWorkerAuth> for DaphneWorker<'srv> {
                     batch_id.to_hex(),
                 )
                 .await
-                .map_err(|e| fatal_error!(err = e))?;
+                .map_err(|e| fatal_error!(err = ?e))?;
         }
 
         durable
@@ -1014,7 +1014,7 @@ impl<'srv> DapLeader<DaphneWorkerAuth> for DaphneWorker<'srv> {
                 (task_id, collect_id, collect_resp),
             )
             .await
-            .map_err(|e| fatal_error!(err = e))?;
+            .map_err(|e| fatal_error!(err = ?e))?;
         Ok(())
     }
 
@@ -1053,7 +1053,7 @@ impl<'srv> DapHelper<DaphneWorkerAuth> for DaphneWorker<'srv> {
                 helper_state_hex,
             )
             .await
-            .map_err(|e| fatal_error!(err = e))?)
+            .map_err(|e| fatal_error!(err = ?e))?)
     }
 
     async fn get_helper_state(
@@ -1073,7 +1073,7 @@ impl<'srv> DapHelper<DaphneWorkerAuth> for DaphneWorker<'srv> {
                 durable_helper_state_name(&task_config.as_ref().version, task_id, agg_job_id),
             )
             .await
-            .map_err(|e| fatal_error!(err = e))?;
+            .map_err(|e| fatal_error!(err = ?e))?;
 
         match res {
             Some(helper_state_hex) => {
diff --git a/daphne_worker/src/metrics.rs b/daphne_worker/src/metrics.rs
index b53c2d5..60dd37d 100644
--- a/daphne_worker/src/metrics.rs
+++ b/daphne_worker/src/metrics.rs
@@ -32,7 +32,7 @@ impl DaphneWorkerMetrics {
             &["host", "code"],
             registry
         )
-        .map_err(|e| fatal_error!(err = e, "failed to register http_status_code"))?;
+        .map_err(|e| fatal_error!(err = ?e, "failed to register http_status_code"))?;
 
         let dap_abort_counter = register_int_counter_vec_with_registry!(
             format!("{front}dap_abort"),
@@ -40,7 +40,7 @@ impl DaphneWorkerMetrics {
             &["host", "reason"],
             registry
         )
-        .map_err(|e| fatal_error!(err = e, "failed to register dap_abort"))?;
+        .map_err(|e| fatal_error!(err = ?e, "failed to register dap_abort"))?;
 
         let daphne = DaphneMetrics::register(registry, prefix)?;
 
diff --git a/daphne_worker/src/tracing_utils/wasm_timing.rs b/daphne_worker/src/tracing_utils/wasm_timing.rs
index 4841962..26e5083 100644
--- a/daphne_worker/src/tracing_utils/wasm_timing.rs
+++ b/daphne_worker/src/tracing_utils/wasm_timing.rs
@@ -69,7 +69,7 @@ pub(crate) fn initialize_timing_histograms(
             .collect(),
         registry,
     )
-    .map_err(|e| fatal_error!(err = e, "failed to register aggregation_request_times"))?;
+    .map_err(|e| fatal_error!(err = ?e, "failed to register aggregation_request_times"))?;
 
     let aggregation_continue_request_times = register_histogram_with_registry!(
         format!("{front}aggregation_continue_request_times"),
@@ -80,7 +80,7 @@ pub(crate) fn initialize_timing_histograms(
             .collect(),
         registry,
     )
-    .map_err(|e| fatal_error!(err = e, "failed to register aggregate_shares_request_times"))?;
+    .map_err(|e| fatal_error!(err = ?e, "failed to register aggregate_shares_request_times"))?;
 
     let aggregate_shares_request_times = register_histogram_with_registry!(
         format!("{front}aggregate_shares_request_times"),
@@ -91,7 +91,7 @@ pub(crate) fn initialize_timing_histograms(
             .collect(),
         registry,
     )
-    .map_err(|e| fatal_error!(err = e, "failed to register upload_request_times"))?;
+    .map_err(|e| fatal_error!(err = ?e, "failed to register upload_request_times"))?;
 
     REQUEST_TIME_HISTOGRAMS.store(Some(Arc::new(RequestTimeHistograms {
         aggregation_init_request_times,


Test patch:
diff --git a/daphne/src/testing.rs b/daphne/src/testing.rs
index 6890c29..e52ce8e 100644
--- a/daphne/src/testing.rs
+++ b/daphne/src/testing.rs
@@ -631,7 +631,7 @@ impl DapHelper<BearerToken> for MockAggregator {
         let mut helper_state_store_mutex_guard = self
             .helper_state_store
             .lock()
-            .map_err(|e| fatal_error!(err = e))?;
+            .map_err(|e| fatal_error!(err = ?e))?;
 
         let helper_state_store = helper_state_store_mutex_guard.deref_mut();
 
@@ -659,7 +659,7 @@ impl DapHelper<BearerToken> for MockAggregator {
         let mut helper_state_store_mutex_guard = self
             .helper_state_store
             .lock()
-            .map_err(|e| fatal_error!(err = e))?;
+            .map_err(|e| fatal_error!(err = ?e))?;
 
         let helper_state_store = helper_state_store_mutex_guard.deref_mut();
 
@@ -774,7 +774,7 @@ impl DapLeader<BearerToken> for MockAggregator {
         let mut leader_state_store_mutex_guard = self
             .leader_state_store
             .lock()
-            .map_err(|e| fatal_error!(err = e))?;
+            .map_err(|e| fatal_error!(err = ?e))?;
         let leader_state_store = leader_state_store_mutex_guard.deref_mut();
 
         // Construct a new Collect URI for this CollectReq.
@@ -788,7 +788,7 @@ impl DapLeader<BearerToken> for MockAggregator {
                 task_id.to_base64url(),
                 collect_id.to_base64url(),
             ))
-            .map_err(|e| fatal_error!(err = e))?;
+            .map_err(|e| fatal_error!(err = ?e))?;
 
         // Store Collect ID and CollectReq into LeaderState.
         let leader_state = leader_state_store.entry(task_id.clone()).or_default();
@@ -810,7 +810,7 @@ impl DapLeader<BearerToken> for MockAggregator {
         let mut leader_state_store_mutex_guard = self
             .leader_state_store
             .lock()
-            .map_err(|e| fatal_error!(err = e))?;
+            .map_err(|e| fatal_error!(err = ?e))?;
         let leader_state_store = leader_state_store_mutex_guard.deref_mut();
 
         let leader_state = leader_state_store
@@ -833,7 +833,7 @@ impl DapLeader<BearerToken> for MockAggregator {
         let mut leader_state_store_mutex_guard = self
             .leader_state_store
             .lock()
-            .map_err(|e| fatal_error!(err = e))?;
+            .map_err(|e| fatal_error!(err = ?e))?;
         let leader_state_store = leader_state_store_mutex_guard.deref_mut();
 
         let mut res = Vec::new();
@@ -859,7 +859,7 @@ impl DapLeader<BearerToken> for MockAggregator {
         let mut leader_state_store_mutex_guard = self
             .leader_state_store
             .lock()
-            .map_err(|e| fatal_error!(err = e))?;
+            .map_err(|e| fatal_error!(err = ?e))?;
         let leader_state_store = leader_state_store_mutex_guard.deref_mut();
 
         let leader_state = leader_state_store