git-ents.gitmain
⌘K
foforge
commit 49e8543
fix: give each 404 copy that matches what was actually missing

not_found() always said No such repository, even for a missing file, directory, commit, or check run inside a repository that resolved just fine, which read as though the whole repository had vanished. It now takes a reason string, and every call site reports what it was actually looking for.

Assisted-by: Claude:claude-sonnet-5

Joseph D. Carpinelli · 1 month ago

Reviews

No reviews of this commit yet — record a verdict below.

Start a review

verdict

crates/git-ents-server/src/web/mod.rs @@ -96,7 +96,7 @@ return route(state, &repo, &rel, rest, query, host, session).await; } - not_found().into_response() + not_found("No such repository.").into_response() } /// Resolve the leading path segments to a repository: the shortest valid prefix @@ -198,12 +198,12 @@ } let Some((repo, rel, rest)) = resolve_repo(&state.data_dir, &segments) else { - return not_found().into_response(); + return not_found("No such repository.").into_response(); }; match rest { ["settings"] => save_settings(state, &repo, &rel, cookie, body).await, ["comment"] => save_comment(state, &repo, &rel, cookie, body).await, - _ => not_found().into_response(), + _ => not_found("No such page.").into_response(), } } @@ -537,7 +537,7 @@ ) .await .into_response(), - _ => not_found().into_response(), + _ => not_found("No such page.").into_response(), } } @@ -763,8 +763,9 @@ ) } -/// A `404` page. -fn not_found() -> (StatusCode, Markup) { +/// A `404` page reporting `reason`, e.g. "No such file." or "No such commit.", +/// so a missing sub-resource does not read as a missing repository. +fn not_found(reason: &str) -> (StatusCode, Markup) { ( StatusCode::NOT_FOUND, page( @@ -772,7 +773,7 @@ html! { div.blankslate { h2 { "404" } - p { "No such repository." } + p { (reason) } a.btn href="/" { "Back to repositories" } } },
crates/git-ents-server/src/web/pages.rs @@ -295,7 +295,7 @@ ) -> Response { let rel = &meta.rel; let Some(selected) = browse_path(sub) else { - return not_found().into_response(); + return not_found("No such file or directory.").into_response(); }; // Classify the selection so the right pane shows a file and the tree expands @@ -314,7 +314,7 @@ .rsplit_once('/') .map_or(String::new(), |(d, _)| d.to_owned()), _ if selected.is_empty() => String::new(), - _ => return not_found().into_response(), + _ => return not_found("No such file or directory.").into_response(), }; // Expand every ancestor directory of the selection (and the selection itself @@ -496,7 +496,7 @@ ) -> Response { let rel = &meta.rel; let Some(dir) = browse_path(sub) else { - return not_found().into_response(); + return not_found("No such directory.").into_response(); }; let spec = if dir.is_empty() { "HEAD".to_owned() @@ -505,7 +505,7 @@ }; let entries = list_tree(repo, &spec).await; if entries.is_empty() && !dir.is_empty() { - return not_found().into_response(); + return not_found("No such directory.").into_response(); } let name = meta.name(); repo_shell( @@ -563,7 +563,7 @@ ) -> Response { let rel = &meta.rel; let Some(path) = browse_path(sub).filter(|p| !p.is_empty()) else { - return not_found().into_response(); + return not_found("No such file.").into_response(); }; let spec = format!("HEAD:{path}"); if git_output(repo, &["cat-file", "-t", &spec]) @@ -571,12 +571,12 @@ .as_deref() != Some("blob\n") { - return not_found().into_response(); + return not_found("No such file.").into_response(); } let Some((bytes, truncated)) = git_output_capped(repo, &["cat-file", "-p", &spec], MAX_RENDER_BYTES).await else { - return not_found().into_response(); + return not_found("No such file.").into_response(); }; let name = path.rsplit('/').next().unwrap_or(&path); let displayable = !truncated && !is_binary(&bytes); @@ -814,7 +814,7 @@ auth: Option<&super::Auth>, ) -> Response { if sha.is_empty() || sha.len() > 64 || !sha.bytes().all(|b| b.is_ascii_hexdigit()) { - return not_found().into_response(); + return not_found("No such commit.").into_response(); } let Some(info) = git_output( repo, @@ -822,14 +822,14 @@ ) .await else { - return not_found().into_response(); + return not_found("No such commit.").into_response(); }; let mut parts = info.split('\u{0}'); let Some(oid) = parts .next() .and_then(|h| ObjectId::from_hex(h.trim().as_bytes()).ok()) else { - return not_found().into_response(); + return not_found("No such commit.").into_response(); }; let author = parts.next().unwrap_or_default().to_owned(); let when = parts.next().and_then(parse_iso); @@ -1076,10 +1076,10 @@ auth: Option<&super::Auth>, ) -> Response { let Some(commit_oid) = ObjectId::from_hex(commit.as_bytes()).ok() else { - return not_found().into_response(); + return not_found("No such check run.").into_response(); }; let Some(outcome) = latest_outcome(repo, commit_oid, name).await else { - return not_found().into_response(); + return not_found("No such check run.").into_response(); }; let short_commit = commit.get(..8).unwrap_or(commit); let rel = &meta.rel; @@ -1140,7 +1140,7 @@ live_runs: &git_effect::engine::LiveRegistry, ) -> Response { let Some(commit_oid) = ObjectId::from_hex(commit.as_bytes()).ok() else { - return not_found().into_response(); + return not_found("No such check run.").into_response(); }; let key = (repo.to_owned(), commit_oid, name.to_owned()); let recording = git_effect::engine::live_snapshot(live_runs, &key); @@ -1169,10 +1169,10 @@ live_runs: &git_effect::engine::LiveRegistry, ) -> Response { let Some(commit_oid) = ObjectId::from_hex(commit.as_bytes()).ok() else { - return not_found().into_response(); + return not_found("No such check run.").into_response(); }; let Some(outcome) = latest_outcome(repo, commit_oid, name).await else { - return not_found().into_response(); + return not_found("No such check run.").into_response(); }; let live = super::render::is_in_progress(outcome.status) .then(|| { @@ -1181,7 +1181,7 @@ }) .flatten(); let Some(recording) = live.or(outcome.recording) else { - return not_found().into_response(); + return not_found("No recording available for this check run.").into_response(); }; let short_commit = commit.get(..8).unwrap_or(commit); let filename = format!(