Ce guide explique comment gérer les erreurs qui se produisent lors de l'exécution d'une étape de flux. Vous pouvez spécifier si une étape ayant échoué nécessite une action de l'utilisateur pour être résolue ou si elle peut être relancée.
- Renvoyez une erreur exploitable : ajoutez un bouton au journal des erreurs qui redirige l'utilisateur vers la fiche de configuration de l'étape, ce qui lui permet de modifier ses entrées pour résoudre l'erreur. Pour marquer une erreur comme exploitable, renvoyez
AddOnsResponseService.ErrorActionability.ACTIONABLE. Pour marquer une erreur comme non actionable, renvoyezAddOnsResponseService.ErrorActionability.NOT_ACTIONABLE. - Réessayer l'étape après une erreur : le flux tente d'exécuter l'étape à nouveau jusqu'à cinq fois avant de s'arrêter. Pour marquer une erreur comme pouvant faire l'objet d'une nouvelle tentative, renvoyez
AddOnsResponseService.ErrorRetryability.RETRYABLE. Pour marquer une erreur qui ne peut pas être relancée, renvoyezAddOnsResponseService.ErrorRetryability.NOT_RETRYABLE.
Vous pouvez également créer des journaux d'erreurs personnalisés avec des chips, des hyperliens et du texte stylisé pour fournir aux utilisateurs un contexte plus détaillé sur l'erreur.
Renvoie une erreur exploitable
L'exemple suivant crée une étape qui demande à un utilisateur un nombre négatif. Si l'utilisateur saisit un nombre positif, l'étape renvoie une erreur exploitable qui l'invite à corriger sa saisie.
Le fichier manifeste suivant définit les entrées et les sorties de l'étape, ainsi que les fonctions à appeler pour la configuration et l'exécution.
JSON
{
"timeZone": "America/Toronto",
"dependencies": {},
"exceptionLogging": "STACKDRIVER",
"runtimeVersion": "V8",
"addOns": {
"common": {
"name": "Retry Errors Example",
"logoUrl": "https://www.gstatic.com/images/icons/material/system/1x/pets_black_48dp.png",
"useLocaleFromApp": true
},
"flows": {
"workflowElements": [
{
"id": "returnElementError",
"state": "ACTIVE",
"name": "Return Element Error Action",
"description": "To notify the user that some error has occurred",
"workflowAction": {
"inputs": [
{
"id": "value1",
"description": "The input from the user",
"cardinality": "SINGLE",
"dataType": {
"basicType": "STRING"
}
}
],
"outputs": [
{
"id": "output_1",
"description": "The output",
"cardinality": "SINGLE",
"dataType": {
"basicType": "STRING"
}
}
],
"onConfigFunction": "onConfiguration",
"onExecuteFunction": "onExecution"
}
}
]
}
}
}
Le code suivant crée la fiche de configuration et gère la logique d'exécution, y compris la gestion des erreurs.
Apps Script
/**
* Returns a configuration card for the step.
* This card contains a text input field for the user.
*/
function onConfiguration() {
let section = CardService.newCardSection()
.addWidget(CardService.newTextInput()
.setFieldName("value1")
.setId("value1")
.setTitle("Please input negative numbers!"));
const card = CardService.newCardBuilder().addSection(section).build();
return card;
}
/**
* Gets an integer value from variable data, handling both string and integer formats.
* @param {Object} variableData The variable data object from the event.
* @return {number} The extracted integer value.
*/
function getIntValue(variableData) {
if (variableData.stringValues) {
return parseInt(variableData.stringValues[0]);
}
return variableData.integerValues[0];
}
/**
* Executes the step.
* If the user input is a positive number, it throws an error and returns an
* actionable error message. Otherwise, it returns the input as an output variable.
* @param {Object} e The event object from the workflow.
*/
function onExecution(e) {
try {
var input_value = getIntValue(e.workflow.actionInvocation.inputs["value1"]);
if (input_value > 0) {
throw new Error('Found invalid positive input value!');
}
// If execution is successful, return the output variable and a log.
const styledText_1 = AddOnsResponseService.newStyledText()
.setText("Execution completed, the number you entered was: ")
.addStyle(AddOnsResponseService.TextStyle.ITALIC)
.addStyle(AddOnsResponseService.TextStyle.UNDERLINE);
const styledText_2 = AddOnsResponseService.newStyledText().setText(input_value)
.setFontWeight(AddOnsResponseService.FontWeight.BOLD);
const workflowAction = AddOnsResponseService.newReturnOutputVariablesAction()
.setVariables({
"output_1": AddOnsResponseService.newVariableData().addStringValue(input_value)
})
.setLog(AddOnsResponseService.newWorkflowTextFormat()
.addTextFormatElement(
AddOnsResponseService.newTextFormatElement().setStyledText(styledText_1)
).addTextFormatElement(
AddOnsResponseService.newTextFormatElement().setStyledText(styledText_2)
));
let hostAppAction = AddOnsResponseService.newHostAppAction().setWorkflowAction(workflowAction);
return AddOnsResponseService.newRenderActionBuilder().setHostAppAction(hostAppAction).build();
} catch (err) {
// If an error occurs, return an actionable error action.
Logger.log('An error occurred: ' + err.message);
const workflowAction = AddOnsResponseService.newReturnElementErrorAction()
// Sets the user-facing error message.
.setErrorLog(
AddOnsResponseService.newWorkflowTextFormat()
.addTextFormatElement(
AddOnsResponseService.newTextFormatElement().setText("Failed because of invalid input values!"))
)
// Makes the error actionable, allowing the user to correct the input.
.setErrorActionability(AddOnsResponseService.ErrorActionability.ACTIONABLE)
// Specifies that the error is not automatically retried.
.setErrorRetryability(AddOnsResponseService.ErrorRetryability.NOT_RETRYABLE);
let hostAppAction = AddOnsResponseService.newHostAppAction().setWorkflowAction(workflowAction);
return AddOnsResponseService.newRenderActionBuilder().setHostAppAction(hostAppAction).build();
}
}
Réessayer l'étape après une erreur
L'exemple suivant crée une étape qui simule un échec temporaire. En cas d'erreur, l'étape renvoie une erreur pouvant être relancée, ce qui entraîne la réexécution de l'étape par le flux.
Le fichier manifeste définit l'étape.
JSON
{
"timeZone": "America/Toronto",
"dependencies": {},
"exceptionLogging": "STACKDRIVER",
"runtimeVersion": "V8",
"addOns": {
"common": {
"name": "Retry Errors Example",
"logoUrl": "https://www.gstatic.com/images/icons/material/system/1x/pets_black_48dp.png",
"useLocaleFromApp": true
},
"flows": {
"workflowElements": [
{
"id": "retryError",
"state": "ACTIVE",
"name": "Retry an error",
"description": "Simulates a temporary failure and retries the step.",
"workflowAction": {
"inputs": [
{
"id": "value1",
"description": "Any input value",
"cardinality": "SINGLE",
"dataType": {
"basicType": "STRING"
}
}
],
"outputs": [
{
"id": "output_1",
"description": "The output",
"cardinality": "SINGLE",
"dataType": {
"basicType": "STRING"
}
}
],
"onConfigFunction": "onRetryConfiguration",
"onExecuteFunction": "onRetryExecution"
}
}
]
}
}
}
Le code suivant crée la fiche de configuration et gère la logique de nouvelle tentative.
Apps Script
/**
* Returns a configuration card for the step.
* This card contains a text input field for the user.
*/
function onRetryConfiguration() {
let section = CardService.newCardSection()
.addWidget(CardService.newTextInput()
.setFieldName("value1")
.setId("value1")
.setTitle("Enter any value"));
const card = CardService.newCardBuilder().addSection(section).build();
return card;
}
/**
* Executes the step and simulates a transient error.
* This function fails 80% of the time. When it fails, it returns an
* error that can be retried.
* @param {Object} e The event object from the workflow.
*/
function onRetryExecution(e) {
try {
// Simulate a transient error that fails 80% of the time.
if (Math.random() < 0.8) {
throw new Error('Simulated transient failure!');
}
// If execution is successful, return the output variable and a log.
var input_value = e.workflow.actionInvocation.inputs["value1"].stringValues[0];
const styledText = AddOnsResponseService.newStyledText()
.setText(`Execution succeeded for input: ${input_value}`);
const workflowAction = AddOnsResponseService.newReturnOutputVariablesAction()
.setVariables({
"output_1": AddOnsResponseService.newVariableData().addStringValue(input_value)
})
.setLog(AddOnsResponseService.newWorkflowTextFormat()
.addTextFormatElement(
AddOnsResponseService.newTextFormatElement().setStyledText(styledText)
));
let hostAppAction = AddOnsResponseService.newHostAppAction().setWorkflowAction(workflowAction);
return AddOnsResponseService.newRenderActionBuilder().setHostAppAction(hostAppAction).build();
} catch (err) {
// If a transient error occurs, return an error message saying the step tries to run again.
Logger.log('A error occurred, trying to run the step again: ' + err.message);
const workflowAction = AddOnsResponseService.newReturnElementErrorAction()
// Sets the user-facing error message.
.setErrorLog(
AddOnsResponseService.newWorkflowTextFormat()
.addTextFormatElement(
AddOnsResponseService.newTextFormatElement().setText("A temporary error occurred. The step will be retried."))
)
// Makes the error not actionable by the user.
.setErrorActionability(AddOnsResponseService.ErrorActionability.NOT_ACTIONABLE)
// Specifies that the error is automatically retried.
.setErrorRetryability(AddOnsResponseService.ErrorRetryability.RETRYABLE);
let hostAppAction = AddOnsResponseService.newHostAppAction().setWorkflowAction(workflowAction);
return AddOnsResponseService.newRenderActionBuilder().setHostAppAction(hostAppAction).build();
}
}