Return actual enum for DeveloperErrors to allow programatic error handling

This commit is contained in:
nab138
2026-02-02 10:23:57 -05:00
parent a944dc79c7
commit ae49b22650
2 changed files with 19 additions and 18 deletions

View File

@@ -8,6 +8,7 @@ use tracing::{error, warn};
use uuid::Uuid; use uuid::Uuid;
use crate::{ use crate::{
SideloadError,
anisette::AnisetteDataGenerator, anisette::AnisetteDataGenerator,
auth::{ auth::{
apple_account::{AppToken, AppleAccount}, apple_account::{AppToken, AppleAccount},
@@ -68,7 +69,7 @@ impl DeveloperSession {
&mut self, &mut self,
url: &str, url: &str,
body: impl Into<Option<Dictionary>>, body: impl Into<Option<Dictionary>>,
) -> Result<(Dictionary, Option<String>), Report> { ) -> Result<(Dictionary, Option<SideloadError>), Report> {
let body = body.into().unwrap_or_else(Dictionary::new); let body = body.into().unwrap_or_else(Dictionary::new);
let base = plist!(dict { let base = plist!(dict {
@@ -108,27 +109,23 @@ impl DeveloperSession {
// 2. We return server errors if the expected data is missing // 2. We return server errors if the expected data is missing
// 3. We return parsing errors if there is no server error but the expected data is missing // 3. We return parsing errors if there is no server error but the expected data is missing
let response_code = dict.get("resultCode").and_then(|v| v.as_signed_integer()); let response_code = dict.get("resultCode").and_then(|v| v.as_signed_integer());
let mut server_error: Option<String> = None; let mut server_error: Option<SideloadError> = None;
if let Some(code) = response_code { if let Some(code) = response_code {
if code != 0 { if code != 0 {
let user_string = dict
.get("userString")
.and_then(|v| v.as_string())
.unwrap_or("Developer request failed.");
let result_string = dict let result_string = dict
.get("resultString") .get("resultString")
.and_then(|v| v.as_string()) .and_then(|v| v.as_string())
.unwrap_or("No error message given."); .unwrap_or("No error message given.");
let user_string = dict
.get("userString")
.and_then(|v| v.as_string())
.unwrap_or(result_string);
server_error = Some(SideloadError::DeveloperError(code, user_string.to_string()));
// if user and result string match, only show one error!(
if user_string == result_string { "Developer request returned error code {}: {} ({})",
server_error = Some(format!("{} Code: {}", user_string, code)); code, user_string, result_string
} else { );
server_error =
Some(format!("{} Code: {}; {}", user_string, code, result_string));
}
error!(server_error);
} }
} else { } else {
warn!("No resultCode in developer request response"); warn!("No resultCode in developer request response");
@@ -148,7 +145,8 @@ impl DeveloperSession {
let result: Result<T, _> = dict.get_struct(response_key); let result: Result<T, _> = dict.get_struct(response_key);
if result.is_err() if result.is_err()
&& let Some(err) = server_error { && let Some(err) = server_error
{
bail!(err); bail!(err);
} }

View File

@@ -18,6 +18,9 @@ pub enum SideloadError {
#[error("Failed to get anisette data, anisette not provisioned")] #[error("Failed to get anisette data, anisette not provisioned")]
AnisetteNotProvisioned, AnisetteNotProvisioned,
#[error("Developer error {0}: {1}")]
DeveloperError(i64, String),
} }
struct ReqwestErrorFormatter; struct ReqwestErrorFormatter;