fix: keep attested Session operation actionable in safe startup summaries

This commit is contained in:
2026-11-04 18:06:13 +09:00
parent 10e16bb77d
commit 1d8c205b2e
3 changed files with 51 additions and 4 deletions
+2 -2
View File
@@ -2347,8 +2347,8 @@ impl RuntimeHttpRestError {
RuntimeError::WorkerExecutionRejected { result, .. } => startup_transfer(result),
_ => None,
};
let message = if startup.is_some() {
"Worker startup failed".to_owned()
let message = if let Some(startup) = &startup {
worker::startup_failure::internal_startup_failure_summary(&startup.primary).to_owned()
} else {
error.to_string()
};
+44
View File
@@ -120,6 +120,20 @@ pub fn reproject_internal_startup_failure(
StartupFailureAttachment::from_projected(&projected)
}
/// Fixed, identifier-free summary for an already authenticated internal caller.
/// Keep the required operation actionable without exposing the source's Display.
/// This neither projects a Browser cause nor chooses an HTTP status.
pub fn internal_startup_failure_summary(failure: &StartupFailureAttachment) -> &'static str {
if failure
.project_for::<InternalTransfer, protocol::session_failure::SessionRegistrationCause>(&())
.is_ok()
{
"Worker startup failed while registering Session (session.record)"
} else {
"Worker startup failed"
}
}
/// Dispatch by the domain attested in process, not by parsing attachment fields.
pub(crate) fn persist_binding_startup_failure<S: session_store::WorkerMetadataStore>(
store: &S,
@@ -249,6 +263,36 @@ mod tests {
WorkerStoreError,
};
#[test]
fn internal_summary_retains_only_attested_required_operation() {
use protocol::session_failure::{SessionPrincipal, SessionRegistrationCause};
let session = protocol::session_failure::session_registration_attachment(
SessionRegistrationCause::denied(SessionPrincipal::Subject),
)
.unwrap();
assert_eq!(
internal_startup_failure_summary(&session),
"Worker startup failed while registering Session (session.record)"
);
let runtime = runtime_startup_attachment(RuntimeStartupCause {
stage: StartupStage::Feature,
reason: RuntimeStartupReason::FeatureFailed,
})
.unwrap();
assert_eq!(
internal_startup_failure_summary(&runtime),
"Worker startup failed"
);
let corrupt = serde_json::from_value(serde_json::json!(
"session.record denied TEST_ONLY_CREDENTIAL /private/path raw_http_body"
))
.unwrap();
assert_eq!(
internal_startup_failure_summary(&corrupt),
"Worker startup failed"
);
}
struct LostSaveResponse(FsWorkerStore);
impl WorkerMetadataStore for LostSaveResponse {
fn write(&self, metadata: &WorkerMetadata) -> Result<(), WorkerStoreError> {
+5 -2
View File
@@ -6772,8 +6772,11 @@ fn embedded_runtime_diagnostic(error: &EmbeddedRuntimeError) -> RuntimeDiagnosti
),
};
if let EmbeddedRuntimeError::WorkerExecutionRejected { result, .. } = error {
if result.startup_failure.is_some() {
projection.message = "Embedded Runtime Worker startup failed".into();
if let Some(primary) = &result.startup_failure {
projection.message = format!(
"Embedded Runtime: {}",
worker::startup_failure::internal_startup_failure_summary(primary)
);
}
projection.startup = result.startup_failure.as_ref().and_then(|primary| {
internal_startup_transfer(runtime_api::WorkerStartupFailure {