Fehler verarbeiten

In dieser Anleitung wird erläutert, wie Sie Workspace Studio-Fehler verwalten, die beim Ausführen eines Schritts auftreten. Fehler werden auf dem Tab „Aktivität“ angezeigt.

Wenn ein Fehler auftritt, können Sie angeben, ob der Schritt Folgendes tun soll:

  • Einen umsetzbaren Fehler zurückgeben: Fügen Sie dem Fehlerprotokoll eine Schaltfläche hinzu, die den Nutzer zur Konfigurationskarte des Schritts weiterleitet. So kann er seine Eingaben ändern, um den Fehler zu beheben. Wenn Sie einen Fehler als umsetzbar markieren möchten, geben Sie AddOnsResponseService.ErrorActionability.ACTIONABLE zurück. Wenn Sie einen Fehler als nicht umsetzbar markieren möchten, geben Sie AddOnsResponseService.ErrorActionability.NOT_ACTIONABLE zurück.
  • Den Schritt nach einem Fehler wiederholen: Der Ablauf versucht bis zu fünf Mal, den Schritt noch einmal auszuführen, bevor er angehalten wird. Wenn Sie einen Fehler als wiederholbar markieren möchten, geben Sie AddOnsResponseService.ErrorRetryability.RETRYABLE zurück. Wenn Sie einen Fehler als nicht wiederholbar markieren möchten, geben Sie AddOnsResponseService.ErrorRetryability.NOT_RETRYABLE zurück.

Sie können auch benutzerdefinierte Fehlerprotokolle erstellen mit Chips, Hyperlinks und formatiertem Text, um Nutzern detailliertere Informationen zum Fehler zu geben.

Einen umsetzbaren Fehler zurückgeben

Im folgenden Beispiel wird ein Schritt erstellt, in dem ein Nutzer nach einer negativen Zahl gefragt wird. Wenn der Nutzer eine positive Zahl eingibt, gibt der Schritt auf dem Tab „Aktivität“ einen umsetzbaren Fehler zurück, der den Nutzer auffordert, seine Eingabe zu korrigieren.

In der folgenden Manifestdatei werden die Ein- und Ausgaben des Schritts sowie die Funktionen definiert, die für die Konfiguration und Ausführung aufgerufen werden sollen.

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

Der folgende Code erstellt die Konfigurationskarte und verarbeitet die Ausführungslogik, einschließlich der Fehlerbehandlung.

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, letting the user 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")
  }
}

Den Schritt nach einem Fehler wiederholen

Im folgenden Beispiel wird ein Schritt erstellt, der einen temporären Fehler simuliert. Wenn ein Fehler auftritt, gibt der Schritt einen wiederholbaren Fehler zurück, wodurch der Ablauf den Schritt noch einmal ausführt.

In der Manifestdatei wird der Schritt definiert.

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

Der folgende Code erstellt die Konfigurationskarte und verarbeitet die Wiederholungslogik.

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('An 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")
  }
}