fix(api): give an expired subtitle candidate a typed error
A grab naming a stale candidate_id now fails as ApiError::SubtitleCandidateExpired (404, code candidate_expired) instead of the generic upstream 503 string the panel had to pattern-match for 'not found'.
This commit is contained in:
@@ -968,7 +968,10 @@ pub async fn grab(
|
||||
let fetched = provider
|
||||
.download(&CandidateId::new(input.candidate_id.clone()))
|
||||
.await
|
||||
.map_err(|error| ApiError::SubtitleUpstream(error.to_string()))?;
|
||||
.map_err(|error| match error {
|
||||
arr_subs::Error::NotFound { .. } => ApiError::SubtitleCandidateExpired,
|
||||
other => ApiError::SubtitleUpstream(other.to_string()),
|
||||
})?;
|
||||
let text = srt_text(&fetched)?;
|
||||
write_sidecar(&destination, &text).await?;
|
||||
|
||||
@@ -2301,6 +2304,28 @@ mod tests {
|
||||
.exists());
|
||||
}
|
||||
|
||||
/// A candidate id does not outlive the search that produced it (issue
|
||||
/// #221): the panel gets a typed `code` to switch on, not a string it has
|
||||
/// to pattern-match against a provider-chosen message.
|
||||
#[tokio::test]
|
||||
async fn a_grab_of_an_expired_candidate_is_a_typed_404() {
|
||||
let fixture = application(vec![Arc::new(DeadProvider)], vec![]).await;
|
||||
|
||||
let (status, body) = grab(
|
||||
&fixture,
|
||||
serde_json::json!({
|
||||
"provider": "dead",
|
||||
"candidate_id": "stale",
|
||||
"language": "pt-PT"
|
||||
}),
|
||||
)
|
||||
.await;
|
||||
|
||||
assert_eq!(status, StatusCode::NOT_FOUND, "{body}");
|
||||
assert_eq!(body["code"], "candidate_expired");
|
||||
assert!(fixture.subtitle_rows().await.is_empty());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn a_grab_naming_an_unconfigured_provider_is_a_422() {
|
||||
let fixture = stub_application().await;
|
||||
|
||||
Reference in New Issue
Block a user