Обработка ошибок

В этом руководстве объясняется, как управлять ошибками Workspace Studio, возникающими при выполнении шага. Ошибки отображаются на вкладке «Действия» .

При возникновении ошибки вы можете указать, следует ли выполнить следующий шаг:

  • Возвращает ошибку, требующую действий : добавляет кнопку в журнал ошибок , которая перенаправляет пользователя на карточку конфигурации шага, позволяя ему изменить свои входные данные для устранения ошибки. Чтобы пометить ошибку как требующую действий, верните AddOnsResponseService.ErrorActionability.ACTIONABLE . Чтобы пометить ошибку как не требующую действий, верните AddOnsResponseService.ErrorActionability.NOT_ACTIONABLE .
  • Повторите шаг после ошибки : процесс попытается выполнить шаг повторно до 5 раз, прежде чем остановиться. Чтобы пометить ошибку как допускающую повторную попытку, верните AddOnsResponseService.ErrorRetryability.RETRYABLE . Чтобы пометить ошибку как не допускающую повторную попытку, верните AddOnsResponseService.ErrorRetryability.NOT_RETRYABLE .

Вы также можете создавать пользовательские журналы ошибок с использованием всплывающих окон, гиперссылок и стилизованного текста, чтобы предоставить пользователям более подробную информацию об ошибке.

Возвращает сообщение об ошибке, требующее принятия мер.

В следующем примере создан шаг, который запрашивает у пользователя отрицательное число. Если пользователь вводит положительное число, шаг возвращает сообщение об ошибке на вкладке «Действия» , предлагающее пользователю исправить введенный текст.

В приведенном ниже файле манифеста определены входные и выходные данные шага, а также функции, которые необходимо вызвать для настройки и выполнения.

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": "handle_error_action",
          "state": "ACTIVE",
          "name": "Handle 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"
          }
        }
      ]
    }
  }
}

Приведенный ниже код создает карту конфигурации и обрабатывает логику выполнения, включая обработку ошибок.

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.
 */
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()
      .setVariableDataMap(
        {
          "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) {
    Logger.log('An error occurred: ' + err.message);

    // If an error occurs, return an actionable error action.
    const workflowAction = AddOnsResponseService.newReturnElementErrorAction()
      // Sets the user-facing error message.
      .setErrorLog(
        AddOnsResponseService.newWorkflowTextFormat()
          .addTextFormatElement(
            AddOnsResponseService.newTextFormatElement()
              .setText("Failed due to 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();

  } finally {
    console.log("Execution completed")
  }
}

Повторите шаг после возникновения ошибки.

В следующем примере создан шаг, имитирующий временный сбой. В случае возникновения ошибки шаг возвращает сообщение об ошибке, которое можно повторить, что приводит к повторному выполнению шага в рамках всего процесса.

Этот шаг определяется файлом манифеста.

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"
          }
        }
      ]
    }
  }
}

Следующий код формирует конфигурационную карту и обрабатывает логику повторных попыток.

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.
 */
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();
  } finally {
    console.log("Execution completed")
  }
}