adjust error messages for text-to-image

This commit is contained in:
Brandon Thomas committed 2025-08-30 16:06:43 -04:00
1 parent c6830a892b
commit de055856e2
13 files changed
+117 -126

No files matched your search

@@ -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<AnyhowError> for GenerateError {
fn from(value: AnyhowError) -> Self {
Self::AnyhowError(value)
}
}
impl From<FalErrorPlus> for GenerateError {
fn from(value: FalErrorPlus) -> Self {
Self::ProviderFailure(ProviderFailureReason::Fal(value))
}
}
impl From<MidjourneyError> for GenerateError {
fn from(value: MidjourneyError) -> Self {
Self::ProviderFailure(ProviderFailureReason::MidjourneyError(value))
}
}
impl From<SoraError> for GenerateError {
fn from(value: SoraError) -> Self {
Self::ProviderFailure(ProviderFailureReason::SoraError(value))
}
}
impl From<StorytellerError> for GenerateError {
fn from(value: StorytellerError) -> Self {
Self::ProviderFailure(ProviderFailureReason::StorytellerError(value))
}
}
@@ -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<AnyhowError> for InternalBgRemovalError {
fn from(value: AnyhowError) -> Self {
Self::AnyhowError(value)
}
}
impl From<StorytellerError> for InternalBgRemovalError {
fn from(value: StorytellerError) -> Self {
Self::StorytellerError(value)
}
}
impl InternalBgRemovalError {
pub fn to_tauri_response<E: Serialize>(&self) -> CommandErrorResponseWrapper<EnqueueImageBgRemovalErrorType, E> {
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,
}
}
}
@@ -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)
@@ -1,3 +1,2 @@
pub mod enqueue_image_bg_removal_command;
pub mod errors;
pub mod generic;
@@ -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<TaskEnqueueSuccess, InternalImageError> {
) -> Result<TaskEnqueueSuccess, GenerateError> {
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<TaskEnqueueSuccess, InternalImageError> {
) -> Result<TaskEnqueueSuccess, GenerateError> {
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)
}
@@ -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<TaskEnqueueSuccess, InternalImageError> {
) -> Result<TaskEnqueueSuccess, GenerateError> {
let priority = provider_priority_store.get_priority()?;
@@ -62,5 +63,5 @@ pub async fn handle_gemini_25_flash(
}
}
Err(InternalImageError::NoProviderAvailable)
Err(GenerateError::NoProviderAvailable)
}
@@ -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<TaskEnqueueSuccess, InternalImageError> {
) -> Result<TaskEnqueueSuccess, GenerateError> {
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)));
}
};
@@ -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<TaskEnqueueSuccess, InternalImageError> {
) -> Result<TaskEnqueueSuccess, GenerateError> {
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));
}
}
}
@@ -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<TaskEnqueueSuccess, InternalImageError> {
) -> Result<TaskEnqueueSuccess, GenerateError> {
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));
}
};
@@ -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<TaskEnqueueSuccess, InternalImageError> {
) -> Result<TaskEnqueueSuccess, GenerateError> {
let priority = provider_priority_store.get_priority()?;
@@ -70,5 +71,5 @@ pub async fn handle_gpt_image_1(
}
}
Err(InternalImageError::NoProviderAvailable)
Err(GenerateError::NoProviderAvailable)
}
@@ -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<TaskEnqueueSuccess, InternalImageError> {
) -> Result<TaskEnqueueSuccess, GenerateError> {
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));
}
};
@@ -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<TaskEnqueueSuccess, InternalImageError> {
) -> Result<TaskEnqueueSuccess, GenerateError> {
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));
}
};
@@ -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<TaskEnqueueSuccess, InternalImageError> {
) -> Result<TaskEnqueueSuccess, GenerateError> {
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<Vec<TextToImageError>>
) -> Result<TaskEnqueueSuccess, InternalImageError> {
) -> Result<TaskEnqueueSuccess, GenerateError> {
if let Some(errors) = maybe_errors {
if !errors.is_empty() {
let messages: Vec<String> = errors.iter()
@@ -141,5 +142,5 @@ fn handle_midjourney_errors(
}
}
Err(InternalImageError::MidjourneyJobEnqueueFailed)
Err(GenerateError::ProviderFailure(ProviderFailureReason::MidjourneyJobEnqueueFailed))
}