Gestion des erreurs
Les workflows Mastra permettent de gérer les erreurs grâce à la vérification du statut du résultat après l’exécution, à des politiques de nouvelle tentative pour les défaillances temporaires et à des fonctions de rappel du cycle de vie pour centraliser la journalisation des erreurs ou les alertes.
Gérer les résultats d’un workflowLien direct vers Gérer les résultats d’un workflow
Lorsque vous exécutez un workflow, l’objet de résultat contient son statut ainsi que les éventuelles erreurs survenues.
Vérifier le statut du résultatLien direct vers Vérifier le statut du résultat
import { mastra } from './mastra'
const workflow = mastra.getWorkflow('myWorkflow')
const run = await workflow.createRun()
const result = await run.start({ inputData: { value: 'test' } })
switch (result.status) {
case 'success':
console.log('Workflow completed:', result.result)
break
case 'failed':
console.error('Workflow failed:', result.error)
break
case 'suspended':
console.log('Workflow suspended, waiting for resume')
break
}
Structure de l’objet de résultatLien direct vers Structure de l’objet de résultat
L’objet de résultat contient les éléments suivants :
status- Le statut du workflow :'success','failed','suspended'ou'tripwire'result- La sortie du workflow (lorsque le statut est'success')error- Les détails de l’erreur (lorsque le statut est'failed')steps- Les résultats de chaque étape, avec leur statut et leur sortie
Accéder aux résultats des étapesLien direct vers Accéder aux résultats des étapes
Vous pouvez examiner le résultat de chaque étape pour déterminer où une défaillance s’est produite :
const result = await run.start({ inputData: { value: 'test' } })
if (result.status === 'failed') {
// Find which step failed
for (const [stepId, stepResult] of Object.entries(result.steps)) {
if (stepResult.status === 'failed') {
console.error(`Step ${stepId} failed:`, stepResult.error)
}
}
}
Fonctions de rappel du cycle de vieLien direct vers Fonctions de rappel du cycle de vie
Lorsque vous devez gérer la fin d’un workflow sans attendre son résultat, par exemple pour des tâches en arrière-plan, des workflows lancés sans attendre leur résultat ou une journalisation centralisée, vous pouvez utiliser des fonctions de rappel du cycle de vie.
onFinishLien direct vers onfinish
Appelé lorsqu’un workflow se termine, quel que soit son statut (succès, échec, suspension ou tripwire) :
import { createWorkflow } from '@mastra/core/workflows'
import { z } from 'zod'
const orderWorkflow = createWorkflow({
id: 'order-processing',
inputSchema: z.object({ orderId: z.string() }),
outputSchema: z.object({ orderId: z.string(), status: z.string() }),
options: {
onFinish: async result => {
if (result.status === 'success') {
await db.updateOrderStatus(result.result.orderId, result.status)
}
await analytics.track('workflow_completed', {
workflowId: 'order-processing',
status: result.status,
})
},
},
})
La fonction de rappel onFinish reçoit :
status- Le statut du workflowresult- La sortie du workflow (en cas de succès)error- Les détails de l’erreur (en cas d’échec)steps- Les résultats de chaque étapetripwire- Les informations sur le tripwire (si le statut est'tripwire')runId- L’identifiant unique de cette exécution du workflowworkflowId- L’identifiant du workflowresourceId- L’identifiant facultatif de la ressource (s’il a été fourni lors de la création de l’exécution)getInitData<any>()- La fonction qui renvoie les données d’entrée initialesmastra- L’instance Mastra (si le workflow est enregistré auprès de Mastra)requestContext- Les données de contexte propres à la requêtelogger- L’instance de journalisation du workflowstate- L’objet représentant l’état actuel du workflow
onErrorLien direct vers onerror
Appelé uniquement lorsqu’un workflow échoue (le statut est 'failed' ou 'tripwire') :
import { createWorkflow } from '@mastra/core/workflows'
import { z } from 'zod'
const paymentWorkflow = createWorkflow({
id: 'payment-processing',
inputSchema: z.object({ amount: z.number() }),
outputSchema: z.object({ transactionId: z.string() }),
options: {
onError: async errorInfo => {
await alertService.notify({
channel: 'payments-alerts',
message: `Payment workflow failed: ${errorInfo.error?.message}`,
})
await errorTracker.capture(errorInfo.error)
},
},
})
La fonction de rappel onError reçoit :
status- Soit'failed', soit'tripwire'error- Les détails de l’erreursteps- Les résultats de chaque étapetripwire- Les informations sur le tripwire (si le statut est'tripwire')runId- L’identifiant unique de cette exécution du workflowworkflowId- L’identifiant du workflowresourceId- L’identifiant facultatif de la ressource (s’il a été fourni lors de la création de l’exécution)getInitData<any>()- La fonction qui renvoie les données d’entrée initialesmastra- L’instance Mastra (si le workflow est enregistré auprès de Mastra)requestContext- Les données de contexte propres à la requêtelogger- L’instance de journalisation du workflowstate- L’objet représentant l’état actuel du workflow
Utiliser les deux fonctions de rappelLien direct vers Utiliser les deux fonctions de rappel
Vous pouvez utiliser les deux fonctions de rappel conjointement :
import { createWorkflow } from '@mastra/core/workflows'
import { z } from 'zod'
const pipelineWorkflow = createWorkflow({
id: 'data-pipeline',
inputSchema: z.object({ source: z.string() }),
outputSchema: z.object({ recordsProcessed: z.number() }),
options: {
onFinish: async result => {
// Always log completion
await logger.info('Pipeline completed', { status: result.status })
},
onError: async errorInfo => {
// Alert on failures
await pagerDuty.alert('Data pipeline failed', errorInfo.error)
},
},
})
Gestion des erreurs dans les fonctions de rappelLien direct vers Gestion des erreurs dans les fonctions de rappel
Les erreurs levées dans les fonctions de rappel sont interceptées et journalisées. Elles n’affectent pas le résultat du workflow et ne provoquent pas son échec. Ainsi, les problèmes rencontrés dans ces fonctions n’interrompent pas vos workflows en production.
options: {
onFinish: async (result) => {
// If this throws, it's logged but the workflow result is unchanged
await externalService.notify(result);
},
}
Nouvelles tentativesLien direct vers Nouvelles tentatives
Mastra propose un mécanisme de nouvelle tentative pour les workflows ou les étapes qui échouent à cause d’erreurs temporaires, par exemple lorsque des étapes interagissent avec des services externes ou des ressources susceptibles d’être momentanément indisponibles.
Au niveau du workflow avec retryConfigLien direct vers workflow-level-using-retryconfig
Vous pouvez configurer les nouvelles tentatives au niveau du workflow. Cette configuration s’applique alors à toutes ses étapes :
import { createWorkflow, createStep } from "@mastra/core/workflows";
import { z } from "zod";
const step1 = createStep({...});
export const testWorkflow = createWorkflow({
retryConfig: {
attempts: 5,
delay: 2000
}
})
.then(step1)
.commit();
Au niveau d’une étape avec retriesLien direct vers step-level-using-retries
Vous pouvez configurer les nouvelles tentatives de chaque étape à l’aide de la propriété retries. Pour l’étape concernée, cette propriété remplace la configuration des nouvelles tentatives définie au niveau du workflow :
import { createWorkflow, createStep } from '@mastra/core/workflows'
import { z } from 'zod'
const step1 = createStep({
execute: async () => {
const response = await fetch('example-url')
if (!response.ok) {
throw new Error('Error')
}
return {
value: '',
}
},
retries: 3,
})
Branchement conditionnelLien direct vers Branchement conditionnel
Vous pouvez utiliser une logique conditionnelle pour créer d’autres chemins d’exécution selon la réussite ou l’échec des étapes précédentes :
import { createWorkflow, createStep } from "@mastra/core/workflows";
import { z } from "zod";
const step1 = createStep({
execute: async () => {
try {
const response = await fetch('example-url');
if (!response.ok) {
throw new Error('error');
}
return {
status: "ok"
};
} catch (error) {
return {
status: "error"
};
}
}
});
const step2 = createStep({...});
const fallback = createStep({...});
export const testWorkflow = createWorkflow({})
.then(step1)
.branch([
[async ({ inputData: { status } }) => status === "ok", step2],
[async ({ inputData: { status } }) => status === "error", fallback]
])
.commit();
Vérifier les résultats des étapes précédentesLien direct vers Vérifier les résultats des étapes précédentes
Utilisez getStepResult() pour examiner les résultats d’une étape précédente.
import { createStep } from "@mastra/core/workflows";
import { z } from "zod";
const step1 = createStep({...});
const step2 = createStep({
execute: async ({ getStepResult }) => {
const step1Result = getStepResult(step1);
return {
value: ""
};
}
});
Quitter prématurément avec bail()Lien direct vers exiting-early-with-bail
Utilisez bail() dans une étape pour quitter prématurément avec un résultat réussi. La charge utile fournie est alors renvoyée comme sortie de l’étape, et l’exécution du workflow prend fin.
import { createWorkflow, createStep } from "@mastra/core/workflows";
import { z } from "zod";
const step1 = createStep({
id: 'step1',
execute: async ({ bail }) => {
return bail({ result: 'bailed' });
},
inputSchema: z.object({ value: z.string() }),
outputSchema: z.object({ result: z.string() }),
});
export const testWorkflow = createWorkflow({...})
.then(step1)
.commit();
Quitter prématurément avec Error()Lien direct vers exiting-early-with-error
Utilisez throw new Error() dans une étape pour quitter avec une erreur.
import { createWorkflow, createStep } from "@mastra/core/workflows";
import { z } from "zod";
const step1 = createStep({
id: 'step1',
execute: async () => {
throw new Error('error');
},
inputSchema: z.object({ value: z.string() }),
outputSchema: z.object({ result: z.string() }),
});
export const testWorkflow = createWorkflow({...})
.then(step1)
.commit();
## Surveiller les erreurs avec stream()
Vous pouvez détecter les erreurs des workflows à l’aide de stream :
import { mastra } from '../src/mastra'
const workflow = mastra.getWorkflow('testWorkflow')
const run = await workflow.createRun()
const stream = await run.stream({
inputData: {
value: 'initial data',
},
})
for await (const chunk of stream.stream) {
console.log(chunk.payload.output.stats)
}