roots: map a forge NotFound to 404 instead of 500
commit
d70b9d7roots: map a forge NotFound to 404 instead of 500
Assisted-by: Claude:claude-fable-5
Reviews
No reviews of this commit yet — record a verdict below.
Start a review
crates/cli/ents-web/src/error.rs
@@ -157,6 +157,12 @@
let status = match &self {
Error::NotFound { .. } => StatusCode::NOT_FOUND,
+ // A forge entity with no ref at all is as much a 404 as this
+ // crate's own NotFound -- the box exists for variant-size
+ // hygiene, not to demote the status to a 500.
+ Error::Forge(inner) if matches!(inner.as_ref(), ents_forge::Error::NotFound { .. }) => {
+ StatusCode::NOT_FOUND
+ }
Error::InvalidArgument(_) | Error::BadCsrf => StatusCode::BAD_REQUEST,
Error::NoSession => StatusCode::UNAUTHORIZED,
Error::Refused(_) | Error::Stale { .. } | Error::Redacted { .. } => {
crates/cli/ents-web/tests/router.rs
@@ -2310,6 +2310,30 @@
);
}
+/// A show page for an id with no ref at all is a real 404, not a 500 --
+/// `ents_forge::Error::NotFound` keeps its status through the `Forge`
+/// box (the box exists for variant-size hygiene only).
+#[tokio::test]
+async fn missing_forge_entity_is_a_404_not_a_500() {
+ let dir = seed_repo(&[("README.md", "# hi\n")]);
+ let state = build_state_at(
+ FixtureIdentity {
+ name: "local-user",
+ key: Keypair::from_seed(1),
+ },
+ dir.path().to_owned(),
+ );
+ let router = ents_web::router(state);
+ for path in ["/issues/nope", "/comments/nope"] {
+ let response = router
+ .clone()
+ .oneshot(Request::get(path).body(Body::empty()).expect("request"))
+ .await
+ .expect("in-process call");
+ assert_eq!(response.status(), StatusCode::NOT_FOUND, "GET {path}");
+ }
+}
+
/// `GET /toolchains` surfaces a toolchain written by an older schema
/// (piece 1's bug: this repository's own
/// `refs/meta/toolchains/{rust,sccache,zig}` still carry it) through the