Answer a file id that does not exist with 404, not 500 (#162)

POST /api/enclosures/{id}/download and DELETE /api/enclosures/{id} raised a missing row with
anyhow!, which ApiError makes a 500 and logs as an api error. A page left open after a feed was
forgotten asks for exactly that: the caller's mistake, a 404 like /media/{id} already answers, and
as a 500 it turned up as a server error in the production check.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-09 01:54:17 +00:00
parent 6ddd6444f9
commit 4db5ee5c44
2 changed files with 3 additions and 2 deletions

View File

@@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed ### Fixed
- Downloading or deleting a file the server no longer has answers "not found" instead of a server error.
- A feed's page in the Directory, and subscribing from it, no longer wait while the whole Directory is put together to check that the one feed is in it. - A feed's page in the Directory, and subscribing from it, no longer wait while the whole Directory is put together to check that the one feed is in it.
- The feed list, and each live update of it, no longer asks the database for a group's title once for every feed in the group. - The feed list, and each live update of it, no longer asks the database for a group's title once for every feed in the group.
- An episode that came as a torrent of several files plays its largest file, and can be deleted, by hand or to free space, instead of staying on disk for good. - An episode that came as a torrent of several files plays its largest file, and can be deleted, by hand or to free space, instead of staying on disk for good.

View File

@@ -1718,7 +1718,7 @@ async fn download_now(
.ctx .ctx
.db .db
.enclosure(id).await? .enclosure(id).await?
.ok_or_else(|| anyhow::anyhow!("no enclosure {id}"))?; .ok_or_else(|| ApiError::not_found(format!("no file {id}")))?;
subscribed(&state, &user, &enc.feed_id).await?; subscribed(&state, &user, &enc.feed_id).await?;
if enc.path.is_some() { if enc.path.is_some() {
return Ok(StatusCode::NO_CONTENT); // Already here. return Ok(StatusCode::NO_CONTENT); // Already here.
@@ -1748,7 +1748,7 @@ async fn delete_file(
.ctx .ctx
.db .db
.enclosure(id).await? .enclosure(id).await?
.ok_or_else(|| anyhow::anyhow!("no enclosure {id}"))?; .ok_or_else(|| ApiError::not_found(format!("no file {id}")))?;
subscribed(&state, &user, &enc.feed_id).await?; subscribed(&state, &user, &enc.feed_id).await?;
// There is one copy of the file: deleting it deletes everyone's. Say so before doing // There is one copy of the file: deleting it deletes everyone's. Say so before doing