From de055856e2b8d4cbdb3ae033abdb1021fc28b355 Mon Sep 17 00:00:00 2001 From: Brandon Thomas Date: Sat, 30 Aug 2025 16:06:43 -0400 Subject: [PATCH] adjust error messages for text-to-image --- .../core/commands/enqueue/generate_error.rs | 62 ++++++++++++++-- .../enqueue/image_bg_removal/errors.rs | 71 ------------------- .../handle_generic_bg_removal_artcraft.rs | 6 +- .../commands/enqueue/image_bg_removal/mod.rs | 1 - .../enqueue_text_to_image_command.rs | 15 ++-- .../gemini_25_flash/handle_gemini_25_flash.rs | 5 +- .../handle_gemini_25_flash_artcraft.rs | 7 +- .../generic/handle_image_artcraft.rs | 19 ++--- .../text_to_image/generic/handle_image_fal.rs | 17 ++--- .../gpt_image_1/handle_gpt_image_1.rs | 5 +- .../handle_gpt_image_1_artcraft.rs | 7 +- .../gpt_image_1/handle_gpt_image_1_sora.rs | 9 +-- .../midjourney/handle_midjourney.rs | 19 ++--- 13 files changed, 117 insertions(+), 126 deletions(-) delete mode 100644 crates/desktop/artcraft/src/core/commands/enqueue/image_bg_removal/errors.rs diff --git a/crates/desktop/artcraft/src/core/commands/enqueue/generate_error.rs b/crates/desktop/artcraft/src/core/commands/enqueue/generate_error.rs index b9a82df460..dea4c8799b 100644 --- a/crates/desktop/artcraft/src/core/commands/enqueue/generate_error.rs +++ b/crates/desktop/artcraft/src/core/commands/enqueue/generate_error.rs @@ -5,19 +5,18 @@ use fal_client::error::fal_error_plus::FalErrorPlus; use midjourney_client::error::midjourney_error::MidjourneyError; use openai_sora_client::sora_error::SoraError; use storyteller_client::error::storyteller_error::StorytellerError; -use crate::core::commands::enqueue::text_to_image::internal_image_error::InternalImageError; #[derive(Debug)] pub enum GenerateError { BadInput(BadInputReason), MissingCredentials(MissingCredentialsReason), - ProviderFailure(ProviderFailure), + ProviderFailure(ProviderFailureReason), /// We couldn't find a provider to dispatch the request to. NoProviderAvailable, /// There was a billing, credits, or payments issue. - BillingIssue, + BillingIssue(BillingIssueReason), /// The feature is not yet implemented. NotYetImplemented(String), @@ -48,7 +47,20 @@ pub enum MissingCredentialsReason { } #[derive(Debug)] -pub enum ProviderFailure { +pub struct BillingIssueReason { + pub provider: BillingProvider, +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum BillingProvider { + Fal, + Midjourney, + Sora, + Storyteller, +} + +#[derive(Debug)] +pub enum ProviderFailureReason { Fal(FalErrorPlus), MidjourneyError(MidjourneyError), /// NB: The midjourney client doesn't categorize all errors, so we have to do so on our end. @@ -57,8 +69,50 @@ pub enum ProviderFailure { StorytellerError(StorytellerError), } +impl GenerateError { + pub fn needs_fal_api_key() -> Self { + Self::MissingCredentials(MissingCredentialsReason::NeedsFalApiKey) + } + + pub fn needs_midjourney_credentials() -> Self { + Self::MissingCredentials(MissingCredentialsReason::NeedsMidjourneyCredentials) + } + + pub fn needs_sora_credentials() -> Self { + Self::MissingCredentials(MissingCredentialsReason::NeedsSoraCredentials) + } + + pub fn needs_storyteller_credentials() -> Self { + Self::MissingCredentials(MissingCredentialsReason::NeedsStorytellerCredentials) + } +} + impl From for GenerateError { fn from(value: AnyhowError) -> Self { Self::AnyhowError(value) } } + +impl From for GenerateError { + fn from(value: FalErrorPlus) -> Self { + Self::ProviderFailure(ProviderFailureReason::Fal(value)) + } +} + +impl From for GenerateError { + fn from(value: MidjourneyError) -> Self { + Self::ProviderFailure(ProviderFailureReason::MidjourneyError(value)) + } +} + +impl From for GenerateError { + fn from(value: SoraError) -> Self { + Self::ProviderFailure(ProviderFailureReason::SoraError(value)) + } +} + +impl From for GenerateError { + fn from(value: StorytellerError) -> Self { + Self::ProviderFailure(ProviderFailureReason::StorytellerError(value)) + } +} diff --git a/crates/desktop/artcraft/src/core/commands/enqueue/image_bg_removal/errors.rs b/crates/desktop/artcraft/src/core/commands/enqueue/image_bg_removal/errors.rs deleted file mode 100644 index 6ff1cef934..0000000000 --- a/crates/desktop/artcraft/src/core/commands/enqueue/image_bg_removal/errors.rs +++ /dev/null @@ -1,71 +0,0 @@ -use crate::core::commands::enqueue::image_bg_removal::enqueue_image_bg_removal_command::EnqueueImageBgRemovalErrorType; -use crate::core::commands::response::failure_response_wrapper::{CommandErrorResponseWrapper, CommandErrorStatus}; -use errors::AnyhowError; -use serde::Serialize; -use storyteller_client::error::storyteller_error::StorytellerError; - -#[derive(Debug)] -pub enum InternalBgRemovalError { - /// No provider is configured for the model type. - NoProviderAvailable, - - /// No storyteller credentials are set. - NeedsStorytellerCredentials, - - /// No image was provided for background removal. - MissingImage, - - /// Could not decode the base64 image data. - Base64DecodeError, - - AnyhowError(AnyhowError), - StorytellerError(StorytellerError), -} - -impl From for InternalBgRemovalError { - fn from(value: AnyhowError) -> Self { - Self::AnyhowError(value) - } -} - -impl From for InternalBgRemovalError { - fn from(value: StorytellerError) -> Self { - Self::StorytellerError(value) - } -} - -impl InternalBgRemovalError { - pub fn to_tauri_response(&self) -> CommandErrorResponseWrapper { - let mut status = CommandErrorStatus::ServerError; - let mut error_type = EnqueueImageBgRemovalErrorType::ServerError; - let mut error_message = "A server error occurred. Please try again. If it continues, please tell our staff about the problem.".to_string(); - - match self { - InternalBgRemovalError::NoProviderAvailable => { - status = CommandErrorStatus::ServerError; - error_type = EnqueueImageBgRemovalErrorType::NoProviderAvailable; - error_message = "No configured provider available for background removal".to_string(); - } - InternalBgRemovalError::MissingImage => { - status = CommandErrorStatus::BadRequest; - error_type = EnqueueImageBgRemovalErrorType::MissingImage; - error_message = "No image provided for background removal".to_string(); - } - InternalBgRemovalError::Base64DecodeError => { - status = CommandErrorStatus::BadRequest; - error_type = EnqueueImageBgRemovalErrorType::Base64DecodeError; - error_message = "Failed to decode base64 image data".to_string(); - } - InternalBgRemovalError::AnyhowError(_) => {} - InternalBgRemovalError::StorytellerError(_) => {} - InternalBgRemovalError::NeedsStorytellerCredentials => {} - } - - CommandErrorResponseWrapper { - status, - error_message: Some(error_message.to_string()), - error_type: Some(error_type), - error_details: None, - } - } -} \ No newline at end of file diff --git a/crates/desktop/artcraft/src/core/commands/enqueue/image_bg_removal/generic/handle_generic_bg_removal_artcraft.rs b/crates/desktop/artcraft/src/core/commands/enqueue/image_bg_removal/generic/handle_generic_bg_removal_artcraft.rs index a527b29619..7fac603b3c 100644 --- a/crates/desktop/artcraft/src/core/commands/enqueue/image_bg_removal/generic/handle_generic_bg_removal_artcraft.rs +++ b/crates/desktop/artcraft/src/core/commands/enqueue/image_bg_removal/generic/handle_generic_bg_removal_artcraft.rs @@ -1,4 +1,4 @@ -use crate::core::commands::enqueue::generate_error::{BadInputReason, GenerateError, MissingCredentialsReason, ProviderFailure}; +use crate::core::commands::enqueue::generate_error::{BadInputReason, GenerateError, MissingCredentialsReason, ProviderFailureReason}; use crate::core::commands::enqueue::image_bg_removal::enqueue_image_bg_removal_command::EnqueueImageBgRemovalCommand; use crate::core::commands::enqueue::image_edit::enqueue_contextual_edit_image_command::{EditImageQuality, EditImageSize, EnqueueContextualEditImageCommand}; use crate::core::commands::enqueue::image_edit::errors::InternalContextualEditImageError; @@ -84,7 +84,7 @@ pub async fn handle_generic_bg_removal_artcraft( } Err(err) => { error!("Failed to use Artcraft background removal: {:?}", err); - return Err(GenerateError::ProviderFailure(ProviderFailure::StorytellerError(err))); + return Err(GenerateError::ProviderFailure(ProviderFailureReason::StorytellerError(err))); } }; @@ -129,7 +129,7 @@ async fn upload_image_from_base64_bytes( }).await .map_err(|err| { error!("Failed to upload image media file: {:?}", err); - GenerateError::ProviderFailure(ProviderFailure::StorytellerError(err)) + GenerateError::ProviderFailure(ProviderFailureReason::StorytellerError(err)) })?; Ok(result.media_file_token) diff --git a/crates/desktop/artcraft/src/core/commands/enqueue/image_bg_removal/mod.rs b/crates/desktop/artcraft/src/core/commands/enqueue/image_bg_removal/mod.rs index 487daacea0..af8f9e640c 100644 --- a/crates/desktop/artcraft/src/core/commands/enqueue/image_bg_removal/mod.rs +++ b/crates/desktop/artcraft/src/core/commands/enqueue/image_bg_removal/mod.rs @@ -1,3 +1,2 @@ pub mod enqueue_image_bg_removal_command; -pub mod errors; pub mod generic; \ No newline at end of file diff --git a/crates/desktop/artcraft/src/core/commands/enqueue/text_to_image/enqueue_text_to_image_command.rs b/crates/desktop/artcraft/src/core/commands/enqueue/text_to_image/enqueue_text_to_image_command.rs index 572564e086..f2763c4244 100644 --- a/crates/desktop/artcraft/src/core/commands/enqueue/text_to_image/enqueue_text_to_image_command.rs +++ b/crates/desktop/artcraft/src/core/commands/enqueue/text_to_image/enqueue_text_to_image_command.rs @@ -1,3 +1,4 @@ +use crate::core::commands::enqueue::generate_error::{BadInputReason, GenerateError, MissingCredentialsReason}; use crate::core::commands::enqueue::task_enqueue_success::TaskEnqueueSuccess; use crate::core::commands::enqueue::text_to_image::gemini_25_flash::handle_gemini_25_flash::handle_gemini_25_flash; use crate::core::commands::enqueue::text_to_image::generic::handle_image_artcraft::handle_image_artcraft; @@ -178,17 +179,17 @@ pub async fn enqueue_text_to_image_command( let mut error_message = "A server error occurred. Please try again. If it continues, please tell our staff about the problem."; match err { - InternalImageError::NoModelSpecified => { + GenerateError::BadInput(BadInputReason::NoModelSpecified) => { status = CommandErrorStatus::BadRequest; error_type = EnqueueTextToImageErrorType::ModelNotSpecified; error_message = "No model specified for image generation"; } - InternalImageError::NoProviderAvailable => { + GenerateError::NoProviderAvailable => { status = CommandErrorStatus::ServerError; error_type = EnqueueTextToImageErrorType::NoProviderAvailable; error_message = "No configured provider available for image generation"; } - InternalImageError::NeedsFalApiKey => { + GenerateError::MissingCredentials(MissingCredentialsReason::NeedsFalApiKey) => { status = CommandErrorStatus::Unauthorized; error_type = EnqueueTextToImageErrorType::NeedsFalApiKey; error_message = "You need to set a FAL api key"; @@ -233,7 +234,7 @@ pub async fn handle_request( fal_task_queue: &FalTaskQueue, sora_creds_manager: &SoraCredentialManager, sora_task_queue: &SoraTaskQueue, -) -> Result { +) -> Result { let result = dispatch_request( &request, @@ -283,11 +284,11 @@ pub async fn dispatch_request( mj_creds_manager: &MidjourneyCredentialManager, sora_creds_manager: &SoraCredentialManager, sora_task_queue: &SoraTaskQueue, -) -> Result { +) -> Result { match request.model { None => { - return Err(InternalImageError::NoModelSpecified); + return Err(GenerateError::BadInput(BadInputReason::NoModelSpecified)); } Some(ImageModel::Gemini25Flash) => { return handle_gemini_25_flash( @@ -343,5 +344,5 @@ pub async fn dispatch_request( } } - Err(InternalImageError::NoProviderAvailable) + Err(GenerateError::NoProviderAvailable) } diff --git a/crates/desktop/artcraft/src/core/commands/enqueue/text_to_image/gemini_25_flash/handle_gemini_25_flash.rs b/crates/desktop/artcraft/src/core/commands/enqueue/text_to_image/gemini_25_flash/handle_gemini_25_flash.rs index 8f64d0ce72..13ec28b9b1 100644 --- a/crates/desktop/artcraft/src/core/commands/enqueue/text_to_image/gemini_25_flash/handle_gemini_25_flash.rs +++ b/crates/desktop/artcraft/src/core/commands/enqueue/text_to_image/gemini_25_flash/handle_gemini_25_flash.rs @@ -1,3 +1,4 @@ +use crate::core::commands::enqueue::generate_error::GenerateError; use crate::core::commands::enqueue::image_edit::errors::InternalContextualEditImageError; use crate::core::commands::enqueue::image_edit::gpt_image_1::handle_gpt_image_1_edit_artcraft::handle_gpt_image_1_edit_artcraft; use crate::core::commands::enqueue::image_edit::gpt_image_1::handle_gpt_image_1_edit_sora::handle_gpt_image_1_edit_sora; @@ -35,7 +36,7 @@ pub async fn handle_gemini_25_flash( storyteller_creds_manager: &StorytellerCredentialManager, sora_creds_manager: &SoraCredentialManager, sora_task_queue: &SoraTaskQueue, -) -> Result { +) -> Result { let priority = provider_priority_store.get_priority()?; @@ -62,5 +63,5 @@ pub async fn handle_gemini_25_flash( } } - Err(InternalImageError::NoProviderAvailable) + Err(GenerateError::NoProviderAvailable) } diff --git a/crates/desktop/artcraft/src/core/commands/enqueue/text_to_image/gemini_25_flash/handle_gemini_25_flash_artcraft.rs b/crates/desktop/artcraft/src/core/commands/enqueue/text_to_image/gemini_25_flash/handle_gemini_25_flash_artcraft.rs index 839c7ca873..ac43d602c6 100644 --- a/crates/desktop/artcraft/src/core/commands/enqueue/text_to_image/gemini_25_flash/handle_gemini_25_flash_artcraft.rs +++ b/crates/desktop/artcraft/src/core/commands/enqueue/text_to_image/gemini_25_flash/handle_gemini_25_flash_artcraft.rs @@ -1,3 +1,4 @@ +use crate::core::commands::enqueue::generate_error::{GenerateError, MissingCredentialsReason, ProviderFailureReason}; use crate::core::commands::enqueue::image_edit::enqueue_contextual_edit_image_command::{EditImageQuality, EditImageSize}; use crate::core::commands::enqueue::image_edit::errors::InternalContextualEditImageError; use crate::core::commands::enqueue::image_inpaint::errors::InternalImageInpaintError; @@ -33,12 +34,12 @@ pub async fn handle_gemini_25_flash_artcraft( request: &EnqueueTextToImageRequest, app_env_configs: &AppEnvConfigs, storyteller_creds_manager: &StorytellerCredentialManager, -) -> Result { +) -> Result { let creds = match storyteller_creds_manager.get_credentials()? { Some(creds) => creds, None => { - return Err(InternalImageError::NeedsStorytellerCredentials); + return Err(GenerateError::MissingCredentials(MissingCredentialsReason::NeedsStorytellerCredentials)); }, }; @@ -78,7 +79,7 @@ pub async fn handle_gemini_25_flash_artcraft( } Err(err) => { error!("Failed to use Artcraft gemini 2.5 flash: {:?}", err); - return Err(InternalImageError::StorytellerError(err)); + return Err(GenerateError::ProviderFailure(ProviderFailureReason::StorytellerError(err))); } }; diff --git a/crates/desktop/artcraft/src/core/commands/enqueue/text_to_image/generic/handle_image_artcraft.rs b/crates/desktop/artcraft/src/core/commands/enqueue/text_to_image/generic/handle_image_artcraft.rs index e86482a615..2231815a38 100644 --- a/crates/desktop/artcraft/src/core/commands/enqueue/text_to_image/generic/handle_image_artcraft.rs +++ b/crates/desktop/artcraft/src/core/commands/enqueue/text_to_image/generic/handle_image_artcraft.rs @@ -1,3 +1,4 @@ +use crate::core::commands::enqueue::generate_error::{BadInputReason, GenerateError}; use crate::core::commands::enqueue::task_enqueue_success::TaskEnqueueSuccess; use crate::core::commands::enqueue::text_to_image::enqueue_text_to_image_command::{EnqueueTextToImageRequest, ImageModel, TextToImageSize}; use crate::core::commands::enqueue::text_to_image::internal_image_error::InternalImageError; @@ -29,7 +30,7 @@ pub async fn handle_image_artcraft( app_env_configs: &AppEnvConfigs, app_data_root: &AppDataRoot, storyteller_creds_manager: &StorytellerCredentialManager, -) -> Result { +) -> Result { let creds = match storyteller_creds_manager.get_credentials()? { Some(creds) => creds, @@ -42,7 +43,7 @@ pub async fn handle_image_artcraft( error!("Failed to emit event: {:?}", err); // Fail open. } - return Err(InternalImageError::NeedsStorytellerCredentials); + return Err(GenerateError::needs_storyteller_credentials()); }, }; @@ -54,17 +55,17 @@ pub async fn handle_image_artcraft( let job_token = match request.model { None => { - return Err(InternalImageError::NoModelSpecified); + return Err(GenerateError::BadInput(BadInputReason::NoModelSpecified)); } Some( ImageModel::Gemini25Flash | ImageModel::GptImage1 | ImageModel::Midjourney ) => { - return Err(InternalImageError::AnyhowError(anyhow!("wrong logic: another branch should handle this: {:?}", request.model))); + return Err(GenerateError::AnyhowError(anyhow!("wrong logic: another branch should handle this: {:?}", request.model))); } Some(ImageModel::Recraft3) => { - return Err(InternalImageError::AnyhowError(anyhow!("not yet implemented in Artcraft"))); + return Err(GenerateError::NotYetImplemented(format!("not yet implemented in Artcraft"))); } Some(ImageModel::Flux1Dev) => { info!("enqueue Flux 1 Dev"); @@ -101,7 +102,7 @@ pub async fn handle_image_artcraft( } Err(err) => { error!("Failed to use Artcraft Flux 1 Dev text to image generation: {:?}", err); - return Err(InternalImageError::StorytellerError(err)); + return Err(GenerateError::from(err)); } } } @@ -140,7 +141,7 @@ pub async fn handle_image_artcraft( } Err(err) => { error!("Failed to use Artcraft Flux 1 Schnell text to image generation: {:?}", err); - return Err(InternalImageError::StorytellerError(err)); + return Err(GenerateError::from(err)); } } } @@ -179,7 +180,7 @@ pub async fn handle_image_artcraft( } Err(err) => { error!("Failed to use Artcraft Flux Pro 1.1 text to image generation: {:?}", err); - return Err(InternalImageError::StorytellerError(err)); + return Err(GenerateError::from(err)); } } } @@ -218,7 +219,7 @@ pub async fn handle_image_artcraft( } Err(err) => { error!("Failed to use Artcraft Flux Pro 1.1 Ultra text to image generation: {:?}", err); - return Err(InternalImageError::StorytellerError(err)); + return Err(GenerateError::from(err)); } } } diff --git a/crates/desktop/artcraft/src/core/commands/enqueue/text_to_image/generic/handle_image_fal.rs b/crates/desktop/artcraft/src/core/commands/enqueue/text_to_image/generic/handle_image_fal.rs index 2c7ba26c03..8c153dfcc0 100644 --- a/crates/desktop/artcraft/src/core/commands/enqueue/text_to_image/generic/handle_image_fal.rs +++ b/crates/desktop/artcraft/src/core/commands/enqueue/text_to_image/generic/handle_image_fal.rs @@ -1,3 +1,4 @@ +use crate::core::commands::enqueue::generate_error::{BadInputReason, GenerateError}; use crate::core::commands::enqueue::task_enqueue_success::TaskEnqueueSuccess; use crate::core::commands::enqueue::text_to_image::enqueue_text_to_image_command::{EnqueueTextToImageRequest, ImageModel}; use crate::core::commands::enqueue::text_to_image::internal_image_error::InternalImageError; @@ -19,7 +20,7 @@ pub async fn handle_image_fal( request: &EnqueueTextToImageRequest, fal_creds_manager: &FalCredentialManager, fal_task_queue: &FalTaskQueue, -) -> Result { +) -> Result { let api_key = match fal_creds_manager.get_key()? { Some(key) => key, @@ -32,14 +33,14 @@ pub async fn handle_image_fal( error!("Failed to emit event: {:?}", err); // Fail open. } - return Err(InternalImageError::NeedsFalApiKey); + return Err(GenerateError::needs_fal_api_key()); }, }; let api_key = fal_creds_manager.get_key_required() .map_err(|err| { error!("EnqueueTextToImage FAL api key required: {:?}", err); - InternalImageError::NeedsFalApiKey + GenerateError::needs_fal_api_key() })?; let prompt = request.prompt.as_deref().unwrap_or(""); @@ -48,13 +49,13 @@ pub async fn handle_image_fal( let result = match request.model { None => { - return Err(InternalImageError::NoModelSpecified); + return Err(GenerateError::BadInput(BadInputReason::NoModelSpecified)); } Some( ImageModel::GptImage1 | ImageModel::Midjourney ) => { - return Err(InternalImageError::AnyhowError(anyhow!("wrong logic: another branch should handle this: {:?}", request.model))); + return Err(GenerateError::AnyhowError(anyhow!("wrong logic: another branch should handle this: {:?}", request.model))); } Some( ImageModel::Gemini25Flash | @@ -62,7 +63,7 @@ pub async fn handle_image_fal( ImageModel::Flux1Schnell | ImageModel::FluxPro11 ) => { - return Err(InternalImageError::AnyhowError(anyhow!("not yet implemented: {:?}", request.model))); + return Err(GenerateError::NotYetImplemented(format!("not yet implemented: {:?}", request.model))); } Some(ImageModel::FluxPro11Ultra) => { model = GenerationModel::FluxPro11Ultra; @@ -98,7 +99,7 @@ pub async fn handle_image_fal( if let Err(err) = fal_task_queue.insert(&enqueued) { error!("Failed to enqueue task: {:?}", err); - return Err(InternalImageError::AnyhowError(anyhow!("Failed to enqueue task: {:?}", err))); + return Err(GenerateError::AnyhowError(anyhow!("Failed to enqueue task: {:?}", err))); } enqueued @@ -117,7 +118,7 @@ pub async fn handle_image_fal( error!("Failed to emit event: {:?}", err); // Fail open. } - return Err(InternalImageError::FalError(err)); + return Err(GenerateError::from(err)); } }; diff --git a/crates/desktop/artcraft/src/core/commands/enqueue/text_to_image/gpt_image_1/handle_gpt_image_1.rs b/crates/desktop/artcraft/src/core/commands/enqueue/text_to_image/gpt_image_1/handle_gpt_image_1.rs index 122664bcee..8b0e4d3fdf 100644 --- a/crates/desktop/artcraft/src/core/commands/enqueue/text_to_image/gpt_image_1/handle_gpt_image_1.rs +++ b/crates/desktop/artcraft/src/core/commands/enqueue/text_to_image/gpt_image_1/handle_gpt_image_1.rs @@ -1,3 +1,4 @@ +use crate::core::commands::enqueue::generate_error::GenerateError; use crate::core::commands::enqueue::image_edit::errors::InternalContextualEditImageError; use crate::core::commands::enqueue::image_edit::gpt_image_1::handle_gpt_image_1_edit_artcraft::handle_gpt_image_1_edit_artcraft; use crate::core::commands::enqueue::image_edit::gpt_image_1::handle_gpt_image_1_edit_sora::handle_gpt_image_1_edit_sora; @@ -34,7 +35,7 @@ pub async fn handle_gpt_image_1( storyteller_creds_manager: &StorytellerCredentialManager, sora_creds_manager: &SoraCredentialManager, sora_task_queue: &SoraTaskQueue, -) -> Result { +) -> Result { let priority = provider_priority_store.get_priority()?; @@ -70,5 +71,5 @@ pub async fn handle_gpt_image_1( } } - Err(InternalImageError::NoProviderAvailable) + Err(GenerateError::NoProviderAvailable) } diff --git a/crates/desktop/artcraft/src/core/commands/enqueue/text_to_image/gpt_image_1/handle_gpt_image_1_artcraft.rs b/crates/desktop/artcraft/src/core/commands/enqueue/text_to_image/gpt_image_1/handle_gpt_image_1_artcraft.rs index 6b5e315678..d96f408378 100644 --- a/crates/desktop/artcraft/src/core/commands/enqueue/text_to_image/gpt_image_1/handle_gpt_image_1_artcraft.rs +++ b/crates/desktop/artcraft/src/core/commands/enqueue/text_to_image/gpt_image_1/handle_gpt_image_1_artcraft.rs @@ -1,3 +1,4 @@ +use crate::core::commands::enqueue::generate_error::GenerateError; use crate::core::commands::enqueue::image_edit::enqueue_contextual_edit_image_command::{EditImageQuality, EditImageSize}; use crate::core::commands::enqueue::image_edit::errors::InternalContextualEditImageError; use crate::core::commands::enqueue::task_enqueue_success::TaskEnqueueSuccess; @@ -30,12 +31,12 @@ pub async fn handle_gpt_image_1_artcraft( request: &EnqueueTextToImageRequest, app_env_configs: &AppEnvConfigs, storyteller_creds_manager: &StorytellerCredentialManager, -) -> Result { +) -> Result { let creds = match storyteller_creds_manager.get_credentials()? { Some(creds) => creds, None => { - return Err(InternalImageError::NeedsStorytellerCredentials); + return Err(GenerateError::needs_storyteller_credentials()); }, }; @@ -101,7 +102,7 @@ pub async fn handle_gpt_image_1_artcraft( } Err(err) => { error!("Failed to use Artcraft gpt-image-1: {:?}", err); - return Err(InternalImageError::StorytellerError(err)); + return Err(GenerateError::from(err)); } }; diff --git a/crates/desktop/artcraft/src/core/commands/enqueue/text_to_image/gpt_image_1/handle_gpt_image_1_sora.rs b/crates/desktop/artcraft/src/core/commands/enqueue/text_to_image/gpt_image_1/handle_gpt_image_1_sora.rs index 292d80f282..be0d257489 100644 --- a/crates/desktop/artcraft/src/core/commands/enqueue/text_to_image/gpt_image_1/handle_gpt_image_1_sora.rs +++ b/crates/desktop/artcraft/src/core/commands/enqueue/text_to_image/gpt_image_1/handle_gpt_image_1_sora.rs @@ -1,3 +1,4 @@ +use crate::core::commands::enqueue::generate_error::GenerateError; use crate::core::commands::enqueue::task_enqueue_success::TaskEnqueueSuccess; use crate::core::commands::enqueue::text_to_image::enqueue_text_to_image_command::{EnqueueTextToImageRequest, TextToImageSize}; use crate::core::commands::enqueue::text_to_image::internal_image_error::InternalImageError; @@ -25,19 +26,19 @@ pub async fn handle_gpt_image_1_sora( app: &AppHandle, sora_creds_manager: &SoraCredentialManager, sora_task_queue: &SoraTaskQueue, -) -> Result { +) -> Result { let mut creds = match sora_creds_manager.get_credentials() { Ok(Some(creds)) => creds, Ok(None) => { error!("Sora credentials not found."); ShowProviderLoginModalEvent::send_for_provider(GenerationProvider::Sora, &app); - return Err(InternalImageError::NeedsSoraCredentials); + return Err(GenerateError::needs_sora_credentials()); } Err(err) => { error!("Error reading Sora credentials: {:?}", err); ShowProviderLoginModalEvent::send_for_provider(GenerationProvider::Sora, &app); - return Err(InternalImageError::NeedsSoraCredentials); + return Err(GenerateError::needs_sora_credentials()); } }; @@ -96,7 +97,7 @@ pub async fn handle_gpt_image_1_sora( error!("Failed to emit event: {:?}", err); // Fail open. } - return Err(InternalImageError::SoraError(err)); + return Err(GenerateError::from(err)); } }; diff --git a/crates/desktop/artcraft/src/core/commands/enqueue/text_to_image/midjourney/handle_midjourney.rs b/crates/desktop/artcraft/src/core/commands/enqueue/text_to_image/midjourney/handle_midjourney.rs index 06a8d1e184..799a71196a 100644 --- a/crates/desktop/artcraft/src/core/commands/enqueue/text_to_image/midjourney/handle_midjourney.rs +++ b/crates/desktop/artcraft/src/core/commands/enqueue/text_to_image/midjourney/handle_midjourney.rs @@ -1,3 +1,4 @@ +use crate::core::commands::enqueue::generate_error::{GenerateError, MissingCredentialsReason, ProviderFailureReason}; use crate::core::commands::enqueue::image_edit::enqueue_contextual_edit_image_command::{EditImageQuality, EditImageSize}; use crate::core::commands::enqueue::image_edit::errors::InternalContextualEditImageError; use crate::core::commands::enqueue::task_enqueue_success::TaskEnqueueSuccess; @@ -41,19 +42,19 @@ pub async fn handle_midjourney( request: &EnqueueTextToImageRequest, app_env_configs: &AppEnvConfigs, mj_creds_manager: &MidjourneyCredentialManager, -) -> Result { +) -> Result { let creds = match mj_creds_manager.maybe_copy_cookie_store() { Ok(Some(creds)) => creds, Ok(None) => { error!("Midjourney credentials not found."); ShowProviderLoginModalEvent::send_for_provider(GenerationProvider::Midjourney, &app); - return Err(InternalImageError::NeedsMidjourneyCredentials); + return Err(GenerateError::needs_midjourney_credentials()); } Err(err) => { error!("Error reading Midjourney credentials: {:?}", err); ShowProviderLoginModalEvent::send_for_provider(GenerationProvider::Midjourney, &app); - return Err(InternalImageError::NeedsMidjourneyCredentials); + return Err(GenerateError::needs_midjourney_credentials()); }, }; @@ -62,11 +63,11 @@ pub async fn handle_midjourney( let user_info = match mj_creds_manager.maybe_copy_user_info() { Ok(Some(user_info)) => user_info, Ok(None) => { - return Err(InternalImageError::NeedsMidjourneyUserInfo); + return Err(GenerateError::MissingCredentials(MissingCredentialsReason::NeedsMidjourneyUserInfo)); } Err(err) => { error!("Error reading Midjourney user info: {:?}", err); - return Err(InternalImageError::NeedsMidjourneyUserInfo); + return Err(GenerateError::MissingCredentials(MissingCredentialsReason::NeedsMidjourneyUserInfo)); }, }; @@ -74,7 +75,7 @@ pub async fn handle_midjourney( Some(user_id) => ChannelId::UserId(user_id), None => { error!("Midjourney user info does not contain a user ID."); - return Err(InternalImageError::NeedsMidjourneyUserId); + return Err(GenerateError::MissingCredentials(MissingCredentialsReason::NeedsMidjourneyUserId)); } }; @@ -97,7 +98,7 @@ pub async fn handle_midjourney( Ok(result) => result, Err(err) => { error!("Failed to use MidJourney: {:?}", err); - return Err(InternalImageError::MidjourneyError(err)); + return Err(GenerateError::from(err)); } }; @@ -122,7 +123,7 @@ pub async fn handle_midjourney( fn handle_midjourney_errors( app: &AppHandle, maybe_errors: Option> -) -> Result { +) -> Result { if let Some(errors) = maybe_errors { if !errors.is_empty() { let messages: Vec = errors.iter() @@ -141,5 +142,5 @@ fn handle_midjourney_errors( } } - Err(InternalImageError::MidjourneyJobEnqueueFailed) + Err(GenerateError::ProviderFailure(ProviderFailureReason::MidjourneyJobEnqueueFailed)) }