platform: handle platform API responses

Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: Iedf8e6d6ecf80a42c24a000f6c787ff56a6a6964
This commit is contained in:
raf 2026-05-01 20:39:46 +03:00
commit 5c5b37b70d
Signed by: NotAShelf
GPG key ID: 29D95B64378DB4BF
2 changed files with 24 additions and 6 deletions

View file

@ -58,6 +58,25 @@ impl CurseForgePlatform {
Ok(headers) Ok(headers)
} }
/// Map a non-success HTTP status to the appropriate `PakkerError`.
fn map_http_error(status: reqwest::StatusCode, context: &str) -> PakkerError {
match status.as_u16() {
404 => PakkerError::ProjectNotFound(context.to_string()),
401 | 403 => {
PakkerError::ConfigError(format!(
"CurseForge API authentication failed ({}). Check your API key.",
status
))
},
_ => {
PakkerError::PlatformApiError(format!(
"CurseForge API returned {} for {}",
status, context
))
},
}
}
const fn map_class_id(class_id: u32) -> ProjectType { const fn map_class_id(class_id: u32) -> ProjectType {
match class_id { match class_id {
12 => ProjectType::ResourcePack, 12 => ProjectType::ResourcePack,
@ -223,7 +242,7 @@ impl CurseForgePlatform {
.await?; .await?;
if !response.status().is_success() { if !response.status().is_success() {
return Err(PakkerError::ProjectNotFound(slug.to_string())); return Err(Self::map_http_error(response.status(), slug));
} }
let result: CurseForgeSearchResponse = response.json().await?; let result: CurseForgeSearchResponse = response.json().await?;
@ -258,6 +277,7 @@ impl PlatformClient for CurseForgePlatform {
let result: CurseForgeProjectResponse = response.json().await?; let result: CurseForgeProjectResponse = response.json().await?;
return Ok(Self::convert_project(result.data)); return Ok(Self::convert_project(result.data));
} }
return Err(Self::map_http_error(response.status(), identifier));
} }
let cf_project = self.search_project_by_slug(identifier).await?; let cf_project = self.search_project_by_slug(identifier).await?;
@ -308,7 +328,7 @@ impl PlatformClient for CurseForgePlatform {
.await?; .await?;
if !response.status().is_success() { if !response.status().is_success() {
return Err(PakkerError::ProjectNotFound(project_id.to_string())); return Err(Self::map_http_error(response.status(), project_id));
} }
let result: CurseForgeFilesResponse = response.json().await?; let result: CurseForgeFilesResponse = response.json().await?;
@ -364,7 +384,7 @@ impl PlatformClient for CurseForgePlatform {
.await?; .await?;
if !response.status().is_success() { if !response.status().is_success() {
return Ok(None); return Err(Self::map_http_error(response.status(), "lookup_by_hash"));
} }
let response_data: serde_json::Value = response.json().await?; let response_data: serde_json::Value = response.json().await?;

View file

@ -38,9 +38,7 @@ impl MultiplatformPlatform {
Err(e) => { Err(e) => {
let is_not_found = matches!( let is_not_found = matches!(
e, e,
PakkerError::ProjectNotFound(_) PakkerError::ProjectNotFound(_) | PakkerError::InvalidResponse(_)
| PakkerError::InvalidResponse(_)
| PakkerError::ConfigError(_)
); );
if is_not_found { Ok(None) } else { Err(e) } if is_not_found { Ok(None) } else { Err(e) }
}, },