[API Node] Better execution error handling (#3587)

Co-authored-by: github-actions <github-actions@github.com>
This commit is contained in:
Chenlei Hu
2025-04-23 11:15:38 -04:00
committed by GitHub
parent 9e10e55633
commit 4c23cfbd4d
11 changed files with 14 additions and 159 deletions

View File

@@ -12,7 +12,7 @@
<ApiNodesList :node-names="apiNodeNames" />
<div class="flex justify-between items-center">
<Button :label="t('g.learnMore')" link />
<Button :label="t('g.learnMore')" link @click="handleLearnMoreClick" />
<div class="flex gap-2">
<Button
:label="t('g.cancel')"
@@ -37,4 +37,8 @@ const { apiNodeNames, onLogin, onCancel } = defineProps<{
onLogin?: () => void
onCancel?: () => void
}>()
const handleLearnMoreClick = () => {
window.open('https://www.comfy.org/faq', '_blank')
}
</script>

View File

@@ -1,47 +0,0 @@
<template>
<div class="flex flex-col items-center gap-4 p-4">
<div class="flex flex-col items-center text-center">
<i class="pi pi-exclamation-circle mb-4" style="font-size: 2rem" />
<h2 class="text-2xl font-semibold mb-2">
{{ $t(`auth.required.${type}.title`) }}
</h2>
<p class="text-gray-600 mb-4 max-w-md">
{{ $t(`auth.required.${type}.message`) }}
</p>
</div>
<div class="flex gap-4">
<Button
class="w-60"
severity="primary"
:label="$t(`auth.required.${type}.action`)"
@click="openPanel"
/>
</div>
</div>
</template>
<script setup lang="ts">
import Button from 'primevue/button'
import { useDialogStore } from '@/stores/dialogStore'
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
const props = defineProps<{
type: 'signIn' | 'credits'
}>()
const dialogStore = useDialogStore()
const authStore = useFirebaseAuthStore()
const openPanel = () => {
// Close the current dialog
dialogStore.closeDialog({ key: 'signin-required' })
// Open user settings and navigate to appropriate panel
if (props.type === 'credits') {
authStore.openCreditsPanel()
} else {
authStore.openSignInPanel()
}
}
</script>

View File

@@ -1122,20 +1122,6 @@
"signOut": "Log Out",
"success": "Signed out successfully",
"successDetail": "You have been signed out of your account."
},
"required": {
"signIn": {
"title": "Sign-In Required to Execute Workflow",
"message": "This workflow includes nodes that require an active account. Please log in or create one to continue.",
"hint": "To login go to: Settings > User > Login",
"action": "Open Settings to Login"
},
"credits": {
"title": "Credits Required to Execute Workflow",
"message": "This workflow includes nodes that require credits. Please add credits to your account to continue.",
"hint": "To add credits go to: Settings > User > Credits",
"action": "Open Settings to Add Credits"
}
}
},
"validation": {

View File

@@ -36,20 +36,6 @@
"termsText": "Al hacer clic en \"Siguiente\" o \"Registrarse\", aceptas nuestros",
"title": "Inicia sesión en tu cuenta"
},
"required": {
"credits": {
"action": "Abrir configuración para añadir créditos",
"hint": "Para añadir créditos ve a: Configuración > Usuario > Créditos",
"message": "Este flujo de trabajo incluye nodos que requieren créditos. Por favor, añade créditos a tu cuenta para continuar.",
"title": "Créditos requeridos para ejecutar el flujo de trabajo"
},
"signIn": {
"action": "Abrir configuración para iniciar sesión",
"hint": "Para iniciar sesión ve a: Configuración > Usuario > Iniciar sesión",
"message": "Este flujo de trabajo incluye nodos que requieren una cuenta activa. Por favor, inicia sesión o crea una para continuar.",
"title": "Inicio de sesión requerido para ejecutar el flujo de trabajo"
}
},
"signOut": {
"signOut": "Cerrar sesión",
"success": "Sesión cerrada correctamente",

View File

@@ -36,20 +36,6 @@
"termsText": "En cliquant sur \"Suivant\" ou \"S'inscrire\", vous acceptez nos",
"title": "Connectez-vous à votre compte"
},
"required": {
"credits": {
"action": "Ouvrir les paramètres pour ajouter des crédits",
"hint": "Pour ajouter des crédits, allez dans : Paramètres > Utilisateur > Crédits",
"message": "Ce workflow inclut des nœuds nécessitant des crédits. Veuillez ajouter des crédits à votre compte pour continuer.",
"title": "Crédits requis pour exécuter le workflow"
},
"signIn": {
"action": "Ouvrir les paramètres pour se connecter",
"hint": "Pour vous connecter, allez dans : Paramètres > Utilisateur > Connexion",
"message": "Ce workflow inclut des nœuds nécessitant un compte actif. Veuillez vous connecter ou en créer un pour continuer.",
"title": "Connexion requise pour exécuter le workflow"
}
},
"signOut": {
"signOut": "Se déconnecter",
"success": "Déconnexion réussie",

View File

@@ -36,20 +36,6 @@
"termsText": "「次へ」または「サインアップ」をクリックすると、私たちの",
"title": "アカウントにログインする"
},
"required": {
"credits": {
"action": "設定を開いてクレジットを追加",
"hint": "クレジットを追加するには: 設定 > ユーザー > クレジット",
"message": "このワークフローにはクレジットが必要なノードが含まれています。続行するにはアカウントにクレジットを追加してください。",
"title": "ワークフロー実行にはクレジットが必要です"
},
"signIn": {
"action": "設定を開いてログイン",
"hint": "ログインするには: 設定 > ユーザー > ログイン",
"message": "このワークフローにはアクティブなアカウントが必要なノードが含まれています。続行するにはログインまたはアカウントを作成してください。",
"title": "ワークフロー実行にはサインインが必要です"
}
},
"signOut": {
"signOut": "ログアウト",
"success": "正常にサインアウトしました",

View File

@@ -36,20 +36,6 @@
"termsText": "\"다음\" 또는 \"가입하기\"를 클릭하면 우리의",
"title": "계정에 로그인"
},
"required": {
"credits": {
"action": "설정에서 크레딧 추가 열기",
"hint": "크레딧을 추가하려면: 설정 > 사용자 > 크레딧 으로 이동하세요.",
"message": "이 워크플로에는 크레딧이 필요한 노드가 포함되어 있습니다. 계속하려면 계정에 크레딧을 추가하세요.",
"title": "워크플로 실행을 위한 크레딧 필요"
},
"signIn": {
"action": "설정에서 로그인 열기",
"hint": "로그인하려면: 설정 > 사용자 > 로그인 으로 이동하세요.",
"message": "이 워크플로에는 활성 계정이 필요한 노드가 포함되어 있습니다. 계속하려면 로그인하거나 계정을 생성하세요.",
"title": "워크플로 실행을 위한 로그인 필요"
}
},
"signOut": {
"signOut": "로그아웃",
"success": "성공적으로 로그아웃되었습니다",

View File

@@ -36,20 +36,6 @@
"termsText": "Нажимая \"Далее\" или \"Зарегистрироваться\", вы соглашаетесь с нашими",
"title": "Войдите в свой аккаунт"
},
"required": {
"credits": {
"action": "Открыть настройки для пополнения кредитов",
"hint": "Чтобы пополнить кредиты, перейдите в: Настройки > Пользователь > Кредиты",
"message": "Этот рабочий процесс содержит узлы, для которых необходимы кредиты. Пожалуйста, пополните баланс, чтобы продолжить.",
"title": "Требуются кредиты для выполнения рабочего процесса"
},
"signIn": {
"action": "Открыть настройки для входа",
"hint": "Чтобы войти, перейдите в: Настройки > Пользователь > Вход",
"message": "Этот рабочий процесс содержит узлы, для которых необходима активная учетная запись. Пожалуйста, войдите или создайте учетную запись, чтобы продолжить.",
"title": "Требуется вход для выполнения рабочего процесса"
}
},
"signOut": {
"signOut": "Выйти",
"success": "Вы успешно вышли из системы",

View File

@@ -36,20 +36,6 @@
"termsText": "点击“下一步”或“注册”即表示您同意我们的",
"title": "登录您的账户"
},
"required": {
"credits": {
"action": "打开设置进行充值",
"hint": "要充值,请前往:设置 > 用户 > 积分",
"message": "此工作流包含需要积分的节点。请为您的账户充值以继续。",
"title": "需要积分以执行工作流"
},
"signIn": {
"action": "打开设置进行登录",
"hint": "要登录,请前往:设置 > 用户 > 登录",
"message": "此工作流包含需要活跃账户的节点。请登录或创建账户以继续。",
"title": "需要登录以执行工作流"
}
},
"signOut": {
"signOut": "退出登录",
"success": "成功退出登录",

View File

@@ -674,13 +674,18 @@ export class ComfyApp {
api.addEventListener('execution_error', ({ detail }) => {
// Check if this is an auth-related error or credits-related error
if (detail.exception_message === 'Please login first to use this node.') {
useDialogService().showSignInRequiredDialog({ type: 'signIn' })
if (
detail.exception_message ===
'Unauthorized: Please login first to use this node.'
) {
useDialogService().showApiNodesSignInDialog([detail.node_type])
} else if (
detail.exception_message ===
'Payment Required: Please add credits to your account to use this node.'
) {
useDialogService().showSignInRequiredDialog({ type: 'credits' })
useDialogService().showTopUpCreditsDialog({
isInsufficientCredits: true
})
} else {
useDialogService().showExecutionErrorDialog(detail)
}

View File

@@ -8,7 +8,6 @@ import MissingModelsWarning from '@/components/dialog/content/MissingModelsWarni
import PromptDialogContent from '@/components/dialog/content/PromptDialogContent.vue'
import SettingDialogContent from '@/components/dialog/content/SettingDialogContent.vue'
import SignInContent from '@/components/dialog/content/SignInContent.vue'
import SignInRequiredDialogContent from '@/components/dialog/content/SignInRequiredDialogContent.vue'
import TopUpCreditsDialogContent from '@/components/dialog/content/TopUpCreditsDialogContent.vue'
import ManagerDialogContent from '@/components/dialog/content/manager/ManagerDialogContent.vue'
import ManagerHeader from '@/components/dialog/content/manager/ManagerHeader.vue'
@@ -348,20 +347,13 @@ export const useDialogService = () => {
})
}
function showSignInRequiredDialog(options: { type: 'signIn' | 'credits' }) {
dialogStore.showDialog({
key: 'signin-required',
component: SignInRequiredDialogContent,
props: options
})
}
function showTopUpCreditsDialog(options?: {
isInsufficientCredits?: boolean
}) {
return dialogStore.showDialog({
key: 'top-up-credits',
component: TopUpCreditsDialogContent,
headerComponent: ComfyOrgHeader,
props: options,
dialogComponentProps: {
pt: {
@@ -384,7 +376,6 @@ export const useDialogService = () => {
showErrorDialog,
showApiNodesSignInDialog,
showSignInDialog,
showSignInRequiredDialog,
showTopUpCreditsDialog,
prompt,
confirm