From 318bfdcafc209c425e432a8cb0922ae5bf8d21b3 Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Thu, 15 Feb 2024 14:44:23 +0100 Subject: [PATCH 01/49] feat(Specification): Refactor error handling Signed-off-by: Charles d'Avernas --- schema/errors.json | 345 ++++++++++++-- schema/workflow.json | 133 +----- specification.md | 1069 +++++++++++++++++++++++++++++------------- 3 files changed, 1066 insertions(+), 481 deletions(-) diff --git a/schema/errors.json b/schema/errors.json index 7e01a8ea..704f01b7 100644 --- a/schema/errors.json +++ b/schema/errors.json @@ -1,54 +1,305 @@ { - "$id": "https://serverlessworkflow.io/schemas/0.8/errors.json", - "$schema": "http://json-schema.org/draft-07/schema#", - "description": "Serverless Workflow specification - errors schema", - "type": "object", - "errors": { - "oneOf": [ - { - "type": "string", - "format": "uri", - "description": "URI to a resource containing error definitions (json or yaml)" - }, - { - "type": "array", - "description": "Workflow Error definitions. Defines checked errors that can be explicitly handled during workflow execution", - "items": { - "type": "object", - "$ref": "#/definitions/errordef" + "$id":"https://serverlessworkflow.io/schemas/0.8/errors.json", + "$schema":"http://json-schema.org/draft-07/schema#", + "description":"Serverless Workflow specification - errors schema", + "type":"object", + "errors":{ + "oneOf":[ + { + "type":"string", + "format":"uri", + "description":"URI to a resource containing workflow error strategy (json or yaml)" }, - "additionalItems": false, - "minItems": 1 - } - ] + { + "type":"object", + "description":"The workflow's error handling configuration, including error definitions, error handlers and error policies", + "properties":{ + "definitions":{ + "type":"array", + "description":"Defines errors that can be explicitly handled and/or thrown during workflow execution", + "items":{ + "$ref":"#/definitions/errorDefinition" + }, + "additionalItems":false, + "minItems":1 + }, + "handlers":{ + "type":"array", + "description":"Defines error handlers used to configure what to do when catching specific errors", + "items":{ + "$ref":"#/definitions/errorHandler" + }, + "additionalItems":false, + "minItems":1 + }, + "policies":{ + "type":"array", + "description":"Defines groups of error handlers that define reusable error policies", + "items":{ + "$ref":"#/definitions/errorPolicy" + }, + "additionalItems":false, + "minItems":1 + } + } + } + ] }, - "required": [ - "errors" + "required":[ + "errors" ], - "definitions": { - "errordef": { - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "Domain-specific error name", - "minLength": 1, - "pattern": "^[a-z0-9](-?[a-z0-9])*$" + "definitions":{ + "errorDefinition":{ + "type":"object", + "properties":{ + "name":{ + "type":"string", + "description":"The name of the error. Must follow the Serverless Workflow Naming Convention.", + "pattern":"^[a-z0-9](-?[a-z0-9])*$" + }, + "source":{ + "type":"string", + "description":"An RFC6901 JSON pointer that precisely identifies the component within a workflow definition (ex: funcRef, subflowRef, ...) from which the described issue originates", + "pattern":"/(\/(([^/~])|(~[01]))*)/g" + }, + "type":{ + "type":"string", + "description":"A RFC3986 URI reference that identifies the problem type. The RFC7807 Problem Details specification encourages that, when dereferenced, it provide human-readable documentation for the problem type (e.g., using HTML)", + "format":"uri" + }, + "status":{ + "type":"integer", + "description":"The status code generated by the origin for an occurrence of a problem. Status codes are extensible by nature and runtimes are not required to understand the meaning of all defined status codes. However, for cross-compatibility purpose, the specification encourages using RFC7231 HTTP Status Codes" + }, + "title":{ + "type":"string", + "description":"A short, human-readable summary of a problem type. It SHOULD NOT change from occurrence to occurrence of a problem, except for purposes of localization" + }, + "detail":{ + "type":"string", + "description":"A human-readable explanation specific to an occurrence of a problem" + } }, - "code": { - "type": "string", - "description": "Error code. Can be used in addition to the name to help runtimes resolve to technical errors/exceptions. Should not be defined if error is set to '*'", - "minLength": 1 + "additionalProperties":false, + "required":[ + "name", + "type", + "status", + "source" + ] + }, + "errorReference":{ + "oneOf":[ + { + "type":"object", + "properties":{ + "refName":{ + "type":"string" + } + }, + "required":[ + "refName" + ], + "additionalProperties":false + }, + { + "type":"object", + "properties":{ + "instance":{ + "type":"string" + }, + "type":{ + "type":"string" + }, + "status":{ + "type":"string" + } + }, + "minProperties":1, + "additionalProperties":false + } + ] + }, + "throw":{ + "oneOf":[ + { + "type":"boolean", + "description":"If true, rethrows the caught error as is" + }, + { + "type":"object", + "anyOf":[ + { + "required":[ + "refName" + ], + "properties":{ + "refName":{ + "type":"string" + } + } + }, + { + "required":[ + "type", + "status" + ], + "properties":{ + "type":{ + "type":"string" + }, + "status":{ + "anyOf":[ + { + "type":"integer" + }, + { + "type":"string" + } + ] + }, + "title":{ + "type":"string" + }, + "detail":{ + "type":"string" + } + } + } + ] + } + ] + }, + "errorHandler":{ + "type":"object", + "properties":{ + "name":{ + "type":"string", + "description":"The unique name which is used to reference the handler.", + "pattern":"^[a-z0-9](-?[a-z0-9])*$" + }, + "when":{ + "type":"array", + "items":{ + "$ref":"#/definitions/errorReference" + }, + "description":"References the errors to handle. If null, and if `exceptWhen` is null, all errors are caught.", + "additionalItems":false, + "minItems":1 + }, + "exceptWhen":{ + "type":"array", + "items":{ + "$ref":"#/definitions/errorReference" + }, + "description":"References the errors not to handle. If null, and if `when` is null, all errors are caught.", + "additionalItems":false, + "minItems":1 + }, + "retry":{ + "oneOf":[ + { + "type":"string", + "description":"The unique name of the retry definition to use" + }, + { + "$ref":"retries.json#/retries/definitions/retrydef", + "description":"The inline retry definition to use" + } + ] + }, + "then":{ + "$ref":"#/definitions/errorOutcomeDefinition" + } }, - "description": { - "type": "string", - "description": "Error description" - } - }, - "additionalProperties": false, - "required": [ - "name" - ] - } + "required":[ + "name" + ] + }, + "errorOutcomeDefinition":{ + "type":"object", + "properties":{ + "compensate":{ + "type":"string", + "description":"Unique Name of a workflow state which is responsible for compensation" + }, + "end":{ + "$ref":"workflow.json#/definitions/end" + }, + "transition":{ + "$ref":"workflow.json#/definitions/transition" + }, + "throw":{ + "$ref":"#/definitions/throw" + } + }, + "minProperties":1, + "maxProperties":1 + }, + "errorHandlerReference":{ + "type":"object", + "oneOf":[ + { + "properties":{ + "refName":{ + "type":"string" + } + }, + "required":[ + "refName" + ] + }, + { + "properties":{ + "when":{ + "type":"array", + "items":{ + "$ref":"#/definitions/errorReference" + } + }, + "exceptWhen":{ + "type":"array", + "items":{ + "$ref":"#/definitions/errorReference" + } + }, + "retry":{ + "oneOf":[ + { + "type":"string" + }, + { + "$ref":"#/definitions/retryDefinition" + } + ] + }, + "then":{ + "$ref":"#/definitions/errorOutcomeDefinition" + } + } + } + ] + }, + "errorPolicy":{ + "type":"object", + "properties":{ + "name":{ + "type":"string", + "description":"The unique name which is used to reference the policy.", + "pattern":"^[a-z0-9](-?[a-z0-9])*$" + }, + "handlers":{ + "type":"array", + "description":"Defines the handlers the policy is made out of", + "items":{ + "$ref":"#/definitions/errorHandlerReference" + }, + "additionalItems":false + } + }, + "required":[ + "name" + ] + } } -} +} \ No newline at end of file diff --git a/schema/workflow.json b/schema/workflow.json index 2b90b79a..f2bd236d 100644 --- a/schema/workflow.json +++ b/schema/workflow.json @@ -94,11 +94,6 @@ "functions": { "$ref": "functions.json#/functions" }, - "autoRetries": { - "type": "boolean", - "default": false, - "description": "If set to true, actions should automatically be retried on unchecked errors. Default is false" - }, "retries": { "$ref": "retries.json#/retries" }, @@ -305,57 +300,18 @@ } ] }, - "error": { - "type": "object", - "properties": { - "errorRef": { + "onerrors": { + "oneOf": [ + { "type": "string", - "description": "Reference to a unique workflow error definition. Used of errorRefs is not used", - "minLength": 1 + "description": "References the error policy to use." }, - "errorRefs": { + { "type": "array", - "description": "References one or more workflow error definitions. Used if errorRef is not used", - "minItems": 1, "items": { - "type": "string" + "$ref": "errors.json#/definitions/errorHandlerReference" }, - "additionalItems": false - }, - "transition": { - "description": "Transition to next state to handle the error.", - "$ref": "#/definitions/transition" - }, - "end": { - "description": "End workflow execution in case of this error.", - "$ref": "#/definitions/end" - } - }, - "additionalProperties": false, - "oneOf": [ - { - "required": [ - "errorRef", - "transition" - ] - }, - { - "required": [ - "errorRef", - "end" - ] - }, - { - "required": [ - "errorRefs", - "transition" - ] - }, - { - "required": [ - "errorRefs", - "end" - ] + "description": "References multiple error handlers." } ] }, @@ -429,23 +385,8 @@ "type": "string", "description": "References a defined workflow retry definition. If not defined the default retry policy is assumed" }, - "nonRetryableErrors": { - "type": "array", - "description": "List of unique references to defined workflow errors for which the action should not be retried. Used only when `autoRetries` is set to `true`", - "minItems": 1, - "items": { - "type": "string" - }, - "additionalItems": false - }, - "retryableErrors": { - "type": "array", - "description": "List of unique references to defined workflow errors for which the action should be retried. Used only when `autoRetries` is set to `false`", - "minItems": 1, - "items": { - "type": "string" - }, - "additionalItems": false + "onErrors":{ + "$ref": "#/definitions/onerrors" }, "actionDataFilter": { "description": "Action data filter", @@ -742,13 +683,7 @@ "$ref": "#/definitions/statedatafilter" }, "onErrors": { - "type": "array", - "description": "States error handling definitions", - "items": { - "type": "object", - "$ref": "#/definitions/error" - }, - "additionalItems": false + "$ref": "#/definitions/onerrors" }, "transition": { "description": "Next transition of the workflow after all the actions have been performed", @@ -841,13 +776,7 @@ "required": [] }, "onErrors": { - "type": "array", - "description": "States error handling definitions", - "items": { - "type": "object", - "$ref": "#/definitions/error" - }, - "additionalItems": false + "$ref": "#/definitions/onerrors" }, "transition": { "description": "Next transition of the workflow after all the actions have been performed", @@ -970,13 +899,7 @@ "description": "Used when completionType is set to 'atLeast' to specify the minimum number of branches that must complete before the state will transition." }, "onErrors": { - "type": "array", - "description": "States error handling definitions", - "items": { - "type": "object", - "$ref": "#/definitions/error" - }, - "additionalItems": false + "$ref": "#/definitions/onerrors" }, "transition": { "description": "Next transition of the workflow after all branches have completed execution", @@ -1087,13 +1010,7 @@ "additionalItems": false }, "onErrors": { - "type": "array", - "description": "States error handling definitions", - "items": { - "type": "object", - "$ref": "#/definitions/error" - }, - "additionalItems": false + "$ref": "#/definitions/onerrors" }, "defaultCondition": { "description": "Default transition of the workflow if there is no matching data conditions. Can include a transition or end definition", @@ -1160,13 +1077,7 @@ "additionalItems": false }, "onErrors": { - "type": "array", - "description": "States error handling definitions", - "items": { - "type": "object", - "$ref": "#/definitions/error" - }, - "additionalItems": false + "$ref": "#/definitions/onerrors" }, "defaultCondition": { "description": "Default transition of the workflow if there is no matching data conditions. Can include a transition or end definition", @@ -1517,13 +1428,7 @@ "$ref": "#/definitions/statedatafilter" }, "onErrors": { - "type": "array", - "description": "States error handling definitions", - "items": { - "type": "object", - "$ref": "#/definitions/error" - }, - "additionalItems": false + "$ref": "#/definitions/onerrors" }, "transition": { "description": "Next transition of the workflow after state has completed", @@ -1643,13 +1548,7 @@ "$ref": "#/definitions/statedatafilter" }, "onErrors": { - "type": "array", - "description": "States error handling definitions", - "items": { - "type": "object", - "$ref": "#/definitions/error" - }, - "additionalItems": false + "$ref": "#/definitions/onerrors" }, "transition": { "description": "Next transition of the workflow after all the actions have been performed", diff --git a/specification.md b/specification.md index 767c67ed..228f051b 100644 --- a/specification.md +++ b/specification.md @@ -60,7 +60,15 @@ - [FunctionRef Definition](#functionref-definition) - [EventRef Definition](#eventref-definition) - [SubFlowRef Definition](#subflowref-definition) + - [Error Handling Configuration](#error-handling-configuration) - [Error Definition](#error-definition) + - [Error Types](#error-types) + - [Error Reference](#error-reference) + - [Error Handler Definition](#error-handler-definition) + - [Error Handler Reference](#error-handler-reference) + - [Error Policy Definition](#error-policy-definition) + - [Error Outcome Definition](#error-outcome-definition) + - [Error Throw Definition](#error-throw-definition) - [Retry Definition](#retry-definition) - [Transition Definition](#transition-definition) - [Switch State Data Conditions](#switch-state-data-conditions) @@ -75,10 +83,19 @@ - [Transitions](#transitions) - [Additional Properties](#additional-properties) * [Workflow Error Handling](#workflow-error-handling) - + [Defining Errors](#defining-errors) - * [Action retries](#action-retries) - + [Retry actions on known errors](#retry-actions-on-known-errors) - + [Automatic retries on known and unknown errors](#automatic-retries-on-known-and-unknown-errors) + + [Error Definitions](#error-definitions) + + [Error Types](#error-types) + + [Error Source](#error-source) + + [Error Handling Strategies](#error-handling-strategies) + - [Error Handlers](#error-handlers) + - [Error Policies](#error-policies) + + [Error Retries](#error-retries) + - [Retry Policy Execution](#retry-policy-execution) + - [Retry Behavior](#retry-behavior) + - [Retry Exhaustion](#retry-exhaustion) + + [Error Outcomes](#error-outcomes) + + [Error Bubbling](#error-bubbling) + + [Error Handling Best Practices](#error-handling-best-practices) * [Workflow Timeouts](#workflow-timeouts) + [Workflow Timeout Definition](#workflow-timeout-definition) - [WorkflowExecTimeout Definition](#workflowexectimeout-definition) @@ -1939,12 +1956,11 @@ definition "id" must be a constant value. | specVersion | Serverless Workflow specification release version | string | yes | | expressionLang | Identifies the expression language used for workflow expressions. Default value is "jq" | string | no | | [timeouts](#Workflow-Timeouts) | Defines the workflow default timeout settings | string or object | no | -| [errors](#Defining-Errors) | Defines checked errors that can be explicitly handled during workflow execution | string or array | no | +| [errors](#error-definitions) | Defines the workflow's error handling configuration, including error definitions, error handlers and error policies | string or [error handling configuration](#error-handling-configuration) | no | | keepActive | If `true`, workflow instances is not terminated when there are no active execution paths. Instance can be terminated with "terminate end definition" or reaching defined "workflowExecTimeout" | boolean | no | | [auth](#Auth-Definition) | Workflow authentication definitions | array or string | no | | [events](#Event-Definition) | Workflow event definitions. | array or string | no | | [functions](#Function-Definition) | Workflow function definitions. Can be either inline function definitions (if array) or URI pointing to a resource containing json/yaml function definitions (if string) | array or string| no | -| autoRetries | If set to `true`, [actions](#Action-Definition) should automatically be retried on unchecked errors. Default is `false` | boolean| no | | [retries](#Retry-Definition) | Workflow retries definitions. Can be either inline retries definitions (if array) or URI pointing to a resource containing json/yaml retry definitions (if string) | array or string| no | | [states](#Workflow-States) | Workflow states | array | yes | | [extensions](#Extensions) | Workflow extensions definitions | array or string | no | @@ -3936,9 +3952,7 @@ This is visualized in the diagram below: | [functionRef](#FunctionRef-Definition) | References a reusable function definition | object or string | yes (if `eventRef` & `subFlowRef` are not defined) | | [eventRef](#EventRef-Definition) | References a `produce` and `consume` reusable event definitions | object | yes (if `functionRef` & `subFlowRef` are not defined) | | [subFlowRef](#SubFlowRef-Definition) | References a workflow to be invoked | object or string | yes (if `eventRef` & `functionRef` are not defined) | -| [retryRef](#retry-definition) | References a defined workflow retry definition. If not defined uses the default runtime retry definition | string | no | -| nonRetryableErrors | List of references to defined [workflow errors](#Defining-Errors) for which the action should not be retried. Used only when `autoRetries` is set to `true` | array | no | -| retryableErrors | List of references to defined [workflow errors](#Defining-Errors) for which the action should be retried. Used only when `autoRetries` is set to `false` | array | no | +| onErrors | Defines the error handling policy to use | string or array of [error handler references](#error-handler-reference) | no | | [actionDataFilter](#Action-data-filters) | Action data filter definition | object | no | | sleep | Defines time periods workflow execution should sleep before / after function execution | object | no | | [condition](#Workflow-Expressions) | Expression, if defined, must evaluate to `true` for this action to be performed. If `false`, action is disregarded | string | no | @@ -4007,17 +4021,7 @@ before and/or after function execution. It can have two properties: Function invocation timeouts should be handled via the states [timeouts](#Workflow-Timeouts) definition. -The `retryRef` property references one of the defined workflow retries by it's unique name. If not set, the action -should be retried according to the default retry policy of the runtime implementation. For more information about workflow -retries reference [this section](#retry-definition). - -The `nonRetryableErrors` property is a list that references one or more unique names of workflow error definitions. -This is the list of known errors for which the action should not be retried for. -It should be used only when the workflow top-level `autoRetries` property is set to `true`. - -The `retryableErrors` property is a list that references one or more unique names of workflow error definitions. -This is the list of known errors for which the action should be retried for. -It should be used only when the workflow top-level `autoRetries` property is set to `false`. +The `onErrors` property can be used to define the error handling policy to use. If a string, references the [error policy definition](#error-policy-definition) to use. Otherwise, defines an array of the [error handlers](#error-handler-reference) to use. The `condition` property is a [workflow expression](#Workflow-Expressions). If defined, it must evaluate to `true` for this action to be performed. If it evaluates to `false` the action is skipped. @@ -4273,13 +4277,119 @@ The default value of this property is `terminate`, meaning that if the parent wo completes, execution of the subflow should be terminated. If it is set to `continue`, if the parent workflow completes, the subflow execution is allowed to continue its own execution. +##### Error Handling Configuration + +| Parameter | Description | Type | Required | +| --- | --- | --- | --- | +| definitions | An array containing reusable definitions of errors to throw and/or to handle. | array of [error definitions](#error-definition) | no | +| handlers | An array containing reusable error handlers, which are used to configure what to do when catching specific errors. | array of [error handler definitions](#error-handler-definition) | no | +| policies | An array containg named groups of error handlers that define reusable error policies | array of [error handling policies](#error-policy-definition) | no | + +
Click to view example definition +

+ + + + + + + + + + +
JSONYAML
+ +```json +{ + "retries": [ + { + "name": "retry-five-times", + "maxAttempts": 5 + } + ], + "errors": { + "definitions": [ + { + "name": "service-not-available-error", + "type": "https://serverlessworkflow.io/spec/errors/communication", + "status": 503, + "title": "Service Not Available", + "detail": "Failed to contact service, even after multiple retries" + } + ], + "handlers": [ + { + "name": "handle-503", + "when": [ + { + "status": 503 + } + ], + "retry": "retry-five-times", + "then": { + "throw": { + "refName": "service-not-available-error" + } + } + } + ], + "policies": [ + { + "name": "fault-tolerance-policy", + "handlers": [ + { + "refName": "handle-503" + } + ] + } + ] + } +} +``` + + + +```yaml +retries: + - name: retry-five-times + maxAttempts: 5 +errors: + definitions: + - name: service-not-available-error + type: https://serverlessworkflow.io/spec/errors/communication + status: 503 + title: Service Not Available + detail: Failed to contact service, even after multiple retries + handlers: + - name: handle-503 + when: + - status: 503 + retry: retry-five-times + then: + throw: + refName: service-not-available-error + policies: + - name: fault-tolerance-policy + handlers: + - refName: handle-503 +``` + +
+ +

+ +Represents the workflow's error handling configuration, including error definitions, error handlers and error policies. + ##### Error Definition | Parameter | Description | Type | Required | | --- | --- | --- | --- | -| errorRef or errorRefs | Reference one unique workflow error definition, or multiple unique workflow error definitions | string (errorRef) or array (errorRefs) | yes | -| [transition](#Transitions) | Transition to next state to handle the error | string or object | yes (if `end` is not defined) | -| [end](#End-Definition) | End workflow execution if this error is encountered | boolean or object | yes (if `transition` is not defined) | +| name | The name of the error. Must follow the [Serverless Workflow Naming Convention](#naming-convention) | string | yes | +| instance | An RFC6901 JSON pointer that precisely identifies the component within a workflow definition (ex: funcRef, subflowRef, ...) from which the described error originates. | string | yes, but is added by runtime when throwing an error | +| type | A RFC3986 URI reference that identifies the error type. The RFC7807 Problem Details specification encourages that, when dereferenced, it provide human-readable documentation for the error type (e.g., using HTML). The specification strongly recommends using [default error types](#error-types) for cross-compatibility concerns. | string | yes | +| status | The status code generated by the origin for an occurrence of an error. Status codes are extensible by nature and runtimes are not required to understand the meaning of all defined status codes. However, for cross-compatibility concerns, the specification encourages using RFC7231 HTTP Status Codes. | string | yes | +| title | A short, human-readable summary of a error type. It SHOULD NOT change from occurrence to occurrence of an error, except for purposes of localization. | string | no | +| detail | A human-readable explanation specific to an occurrence of an error. | string | no |
Click to view example definition

@@ -4294,8 +4404,11 @@ If it is set to `continue`, if the parent workflow completes, the subflow execut ```json { - "errorRef": "Item not in inventory", - "transition": "IssueRefundToCustomer" + "instance": "/states/0/actions/0", + "type": "https://example.com/errors#timeout", + "status": 504, + "title": "Function Timeout", + "detail": "The function 'my-function' timed out." } ``` @@ -4303,8 +4416,11 @@ If it is set to `continue`, if the parent workflow completes, the subflow execut ```yaml -errorRef: Item not in inventory -transition: IssueRefundToCustomer +instance: "/states/0/actions/0" +type: "https://example.com/errors#timeout" +status: 504 +title: "Function Timeout" +detail: "The function 'my-function' timed out." ``` @@ -4313,28 +4429,415 @@ transition: IssueRefundToCustomer

-Error definitions describe checked errors that can occur during workflow execution and how to handle them. +Error definitions are [RFC7807](https://datatracker.ietf.org/doc/html/rfc7807) compliant descriptions of errors that are produced by/originating from the execution of a workflow. Runtimes use them to describe workflow related errors in a user-friendly, technology agnostic and cross-platform way. + +Property `instance` identifies the component within a workflow definition from which the described error originates. It is set by runtimes when throwing an error. + +For example, in the above definition, the source '/states/0/actions/0' indicates that the error originates from the execution of the first action of the first state of the workflow definitions. +This helps both users and implementers to describe and communicate about origins of errors without technical, technology/platform specific knowledge or understanding. -The `errorRef` property references the unique workflow error definition. For more info on workflow error handling -referece [this section](#Defining-Errors). +Property `type` is an URI used to identify the type of the error. +**For cross-compatibility concerns, the specification strongly encourage using the [default types](#default-error-types).** -The `errorRefs`property references at least one of the defined workflow error definitions. -Can be used when `errorRef` is not used. Usable when you want to define multiple error refs for which the same transition -or end definition should be applied.For more info on workflow error handling -referece [this section](#Defining-Errors). +Property `status` identifies the error's status code. +**For cross-compatibility concerns, the specification strongly encourage using [HTTP Status Codes](https://datatracker.ietf.org/doc/html/rfc7231#section-6.1).** -Note that the `errorRef` and `errorRefs` properties are mutually exclusive, meaning that you can only specify one or the other, -but not both at the same time. +Properties `title` and `detail` are used to provide additional information about the error. -The `transition` property defines the transition to the next workflow state in cases when the defined -error happens during runtime execution. +Note that an error definition should **NOT** carry any implementation-specific information such as stack traces or code references: its purpose is to provide users a consistent, human-readable description of an error. -If `transition` is not defined you can also define the `end` property which will end workflow execution at that point. -Note that the `transition` and `end` properties are mutually exclusive, meaning that you can only specify one or the other, -but not both at the same time. +##### Error Types + +| Type | Status | Description +| --- | --- | --- | +| [https://serverlessworkflow.io/spec/errors/configuration](#) | 400 | Errors resulting from incorrect or invalid configuration settings, such as missing or misconfigured environment variables, incorrect parameter values, or configuration file errors. | +| [https://serverlessworkflow.io/spec/errors/validation](#) | 400 | Errors arising from validation processes, such as validation of input data, schema validation failures, or validation constraints not being met. These errors indicate that the provided data or configuration does not adhere to the expected format or requirements specified by the workflow. | +| [https://serverlessworkflow.io/spec/errors/expression](#) | 400 | Errors occurring during the evaluation of runtime expressions, such as invalid syntax or unsupported operations. | +| [https://serverlessworkflow.io/spec/errors/authentication](#) | 401 | Errors related to authentication failures. | +| [https://serverlessworkflow.io/spec/errors/authorization](#) | 403 | Errors related to unauthorized access attempts or insufficient permissions to perform certain actions within the workflow. | +| [https://serverlessworkflow.io/spec/errors/timeout](#) | 408 | Errors caused by timeouts during the execution of tasks or during interactions with external services. | +| [https://serverlessworkflow.io/spec/errors/communication](#) | 500 | Errors encountered while communicating with external services, including network errors, service unavailable, or invalid responses. | +| [https://serverlessworkflow.io/spec/errors/runtime](#) | 500 | Errors occurring during the runtime execution of a workflow, including unexpected exceptions, errors related to resource allocation, or failures in handling workflow tasks. These errors typically occur during the actual execution of workflow components and may require runtime-specific handling and resolution strategies. | + +The specification promotes the use of default error types by runtimes and workflow authors for describing thrown [errors](#error-definition). This approach ensures consistent identification, handling, and behavior across various platforms and implementations. + +##### Error Reference + +| Parameter | Description | Type | Required | +| --- | --- | --- | --- | +| refName | The name of the error definition to reference. If set, all other properties are ignored. | string | no | +| instance | An RFC6901 JSON pointer that precisely identifies the component within a workflow definition from which the error to reference originates | string | no | +| type | A RFC3986 URI reference that identifies the type of error(s) to reference | string | no | +| status | The status code of the error(s) to reference | string | no | + +
Click to view example definition +

+ + + + + + + + + + +
JSONYAML
+ +```json +{ + "type": "https://example.com/errors#timeout", + "status": 504 +} +``` + + + +```yaml +type: "https://example.com/errors#timeout" +status: 504 +``` + +
+ +

+ +An Error Reference in a Serverless Workflow provides a means to point to specific error instances or types within the workflow definition. It serves as a convenient way to refer to errors without duplicating their definitions. + +If multiple properties are set, they are considered as cumulative conditions to match an error. + +For example, the above definition is the same than saying "match errors with `type` 'https://example.com/errors#timeout' AND with `status` '504'". + +##### Error Handler Definition + +| Parameter | Description | Type | Required | +| --- | --- | --- | --- | +| name | The unique name which is used to reference the defined handler. | string | yes | +| when | References the errors to handle. If null or empty, and if `exceptWhen` is null or empty, all errors are caught. | array of [error references](#error-reference) | no | +| exceptWhen | References the errors not to handle. If null or empty, and if `when` is null or empty, all errors are caught. | array of [error references](#error-reference) | no | +| retry | The retry policy to use, if any. If a string, references an existing [retry definition](#retry-definition). | string or [retry definition](#retry-definition) | no | +| then | Defines the outcome, if any, when handling errors | [error outcome definition](#error-outcome-definition) | no | + +
Click to view example definition +

+ + + + + + + + + + +
JSONYAML
+ +```json +{ + "errors": { + "handlers": [ + { + "name": "handle-invalid-error", + "when": [ + { "error": "invalid" }, + { "status": 404 }, + { "status": 403 } + ], + "then": { + "transition": "my-state" + } + }, + { + "name": "handle-timeout-error", + "when": [ + { "status": 503 } + ], + "retry": "my-retry-policy", + "then": { + "transition": "my-state" + } + } + ] + } +} +``` + + + +```yaml +errors: + handlers: + - name: 'handle-invalid-error' + when: + - type: 'invalid' + - status: 404 + - status: 403 + then: + transition: 'my-state' + - name: 'handle-timeout-error' + when: + - status: 503 + retry: 'my-retry-policy' + then: + transition: 'my-state' +``` + +
+ +

+ +Error handler definitions specify which errors to handle and how they should be handled within a workflow. + +The `name` property specifies the distinct identifier utilized to reference the error handler. + +The `when` property defines the specific errors to handle. Allows for handling only specific errors. + +The `exceptWhen` property defines the specified errors NOT to handle. Allows for handling all errors, excluding specific ones. + +The `retry` property serves to either reference an existing retry policy or define a new one to be employed when handling specified errors within the workflow. If a retry policy is designated, the error source identified by the [error source](#error-source) will undergo retries according to the guidelines outlined in the associated [policy](#retry-definition). In the event that a retry attempt is successful, the workflow seamlessly proceeds as though the error had not transpired. However, if the maximum number of configured retry attempts is exhausted without success, the workflow proceeds to execute the error outcome stipulated by the `then` property. + +The `then` property defines caught errors outcome, if any. If not defined, caught errors will be considered as handled, and the execution of the workflow will continue as if the error never occured. Handled errors that are not [rethrown](#error-outcome-definition) do NOT [bubble up](#error-bubbling). For more information, see the [Workflow Error Handling](#Workflow-Error-Handling) sections. +##### Error Handler Reference + +| Parameter | Description | Type | Required | +| --- | --- | --- | --- | +| refName | The name of the error handler definition to reference. If set, all other properties are ignored. | string | no | +| when | References the errors to handle. If null or empty, and if `exceptWhen` is null or empty, all errors are caught. | array of [errorRefs](#error-reference) | no | +| exceptWhen | References the errors not to handle. If null or empty, and if `when` is null or empty, all errors are caught. | array of [errorRefs](#error-reference) | no | +| retry | The retry policy to use, if any. If a string, references an existing [retry definition](#retry-definition). | string or [retry definition](#retry-definition) | no | +| then | Defines the outcome, if any, when handling errors | [outcomeDef](#outcome-definition) | no | + + +
Click to view example definition +

+ + + + + + + + + + +
JSONYAML
+ +```json +{ + "errors": { + "policies": [ + { + "name": "my-retry-policy", + "handlers": [ + { + "refName": "handle-timeout-error" + }, + { + "when": [ + { "status": 503 } + ], + "retry": "my-retry-policy" + } + ] + } + ] + } +} +``` + + + +```yaml +errors: + policies: + - name: 'my-retry-policy' + handlers: + - refName: 'handle-timeout-error' + - when: + - status: 503 + retry: 'my-retry-policy' +``` + +
+ +

+ +Error Handler References streamline the error handling process by enabling workflows to leverage established error handling logic. + +By referencing pre-defined error handler definitions, workflows can ensure consistency and reusability of error handling strategies, promoting maintainability and clarity within the workflow definition. + +##### Error Policy Definition + +| Parameter | Description | Type | Required | +| --- | --- | --- | --- | +| name | The name of the error handler | string | yes | +| handlers | A list of the error handlers to use | array of [error handler references](#error-handler-reference) | yes | + +
Click to view example definition +

+ + + + + + + + + + +
JSONYAML
+ +```json +{ + "errors": { + "policies": [ + { + "name": "my-retry-policy", + "handlers": [ + { + "refName": "handle-timeout-error" + }, + { + "when": [ + { "status": 503 } + ], + "retry": "my-retry-policy" + } + ] + } + ] + } +} +``` + + + +```yaml +errors: + policies: + - name: 'my-retry-policy' + handlers: + - refName: 'handle-timeout-error' + - when: + - status: 503 + retry: 'my-retry-policy' +``` + +
+ +

+ +Error Policy Definition in a Serverless Workflow specifies a named collection of error handlers to be applied for error handling within the workflow. They are used to streamline error handling by organizing and grouping error handlers into reusable sets. + +By defining error policies, workflows can easily apply consistent error handling strategies across multiple components or states within the workflow, promoting modularity and maintainability of the workflow definition. + +##### Error Outcome Definition + +| Parameter | Description | Type | Required | +| --- | --- | --- | --- | +| compensate | If `true`, triggers workflow compensation, then proceeds to the current state's outcome. | boolean | yes if `end`, `transition` and `throw` are null, otherwise no. | +| end | If `true`, ends the workflow. | boolean or [end definition](#end-definition) | yes if `compensate`, `transition` and `throw` are null, otherwise no. | +| transition | Indicates that the the workflow should transition to the specified state when the error is handled. All potential other activities are terminated. | string or [transition](#transition-definition). | yes if `compensate`, `end` and `throw` are null, otherwise no. | +| throw | Indicates that the handled error should be rethrown. If true, the error is re-thrown as is. Otherwise, configures the error to throw, potentially using runtime expressions. | boolean or [error throw definition](#error-throw-definition). | yes if `compensate`, `end` and `transition` are null, otherwise no. | + +
Click to view example definition +

+ + + + + + + + + + +
JSONYAML
+ +```json +{ + "when": [ + { + "status": 503 + } + ], + "then": { + "transition": "my-state" + } +} +``` + + + +```yaml +when: + - status: 503 +then: + transition: 'my-state' +``` + +
+ +

+ +Error Outcome Definitions provide a flexible mechanism for defining the behavior of the workflow after handling errors. + +By specifying actions such as compensation, ending the workflow, retrying failed actions, transitioning to specific states, or rethrowing errors, Error Outcome Definitions enable precise error handling strategies tailored to the workflow's requirements. + +##### Error Throw Definition + +| Parameter | Description | Type | Required | +| --- | --- | --- | --- | +| refName | The name of the [error definition](#error-definition) to throw. If set, all other properties are ignored. | string | yes, if no other property has been set, otherwise no. | +| type | The URI reference that identifies the type of error to throw. Supports runtime expressions. | string | yes if `name` has not been set, otherwise no. | +| status | The status code generated by the origin for an occurrence of a problem. Supports runtime expressions. | integer or string | yes if `name` has not been set, otherwise no. | +| title | A short, human-readable summary of a problem type. Supports runtime expressions. | string | no | +| detail | A human-readable explanation specific to an occurrence of a problem. Supports runtime expressions. | string | no | + +
Click to view example definition +

+ + + + + + + + + + +
JSONYAML
+ +```json +{ + "throw": { + "type": "https://serverlessworkflow.io/spec/errors/runtime", + "status": 400, + "detail": "${ $CONST.localizedErrorDetail }" + } +} +``` + + + +```yaml +throw: + type: https://serverlessworkflow.io/spec/errors/runtime + status: 400 + detail: ${ $CONST.localizedErrorDetail } +``` + +
+ +

+ +Error Throw Definitions provide a mechanism for throwing custom errors within the workflow. + +By specifying the error to be thrown and optionally providing a runtime expression, Error Throw Definitions enable workflows to generate and throw errors dynamically, enhancing flexibility and adaptability in error handling strategies. + ##### Retry Definition | Parameter | Description | Type | Required | @@ -5187,71 +5690,35 @@ Note the same can be also specified using workflow metadata, which is the prefer ### Workflow Error Handling -Serverless Workflow language allows you to define `explicit` error handling, meaning you can define what should happen -in case of errors inside your workflow model rather than some generic error handling entity. -This allows error handling to become part of your orchestration activities and as such part of your business problem -solutions. - -The idea behind the way Serverless Workflow defines error handling is that workflows should only fail due to unknown bugs -during execution. In general, you should always write your workflows so that they do not fail on any known failures. - -Each workflow state can define error handling, which is related only to errors that may arise during its -execution. Error handling defined in one state cannot be used to handle errors that happened during execution of another state -during workflow execution. +Error handling is a crucial aspect of any workflow system, ensuring that the workflow can gracefully handle unexpected situations or errors that may occur during its execution. In ServerlessWorkflow, error handling is a well-defined and structured process aimed at providing developers with the tools and mechanisms necessary to manage errors effectively within their workflows. -Unknown errors that may arise during workflow state execution that are not explicitly handled within the workflow definition -should be reported by runtime implementations and halt workflow execution. +#### Error Definitions -Within workflow definitions, errors defined are `domain specific`, meaning they are defined within -the actual business domain, rather than their technical (programming-language-specific) description. +[Error definitions](#error-definition) in ServerlessWorkflow follow the [RFC7807 Problem Details specification](https://datatracker.ietf.org/doc/html/rfc7807), providing a standardized format for describing errors that may occur during workflow execution. These definitions include parameters such as name, instance, type, status, title, and detail, which collectively provide a comprehensive description of the error. By adhering to this standard, errors can be described in a consistent, technology-agnostic, and human-readable manner, facilitating effective communication and resolution. -For example, we can define errors such as "Order not found", or "Item not in inventory", rather than having to -use terms such as "java.lang.IllegalAccessError", or "response.status == 404", which -might make little to no sense to our specific problem domain, as well as may not be portable across various runtime implementations. +#### Error Types -In addition to the domain specific error name, users have the option to also add an optional error code -to help runtime implementations with mapping defined errors to concrete underlying technical ones. +ServerlessWorkflow defines a set of [default error types](#error-types), each identified by a unique URI reference and associated with specific status code(s). These error types cover common scenarios such as configuration errors, validation failures, authentication issues, timeouts, and runtime exceptions. By utilizing these predefined error types, workflows can maintain cross-compatibility and ensure consistent error identification and handling across different platforms and implementations. -Runtime implementations must be able to map the error domain specific name (and the optional error code) -to concrete technical errors that arise during workflow execution. +#### Error Source -#### Defining Errors +In Serverless Workflow, the concept of "Error Source" refers to the precise origin or location within the workflow definition where an error occurs during its execution. This crucial aspect is identified and pinpointed using the [error definition's ](#error-definition) `instance` property, which is defined as an [RFC6901 JSON pointer](https://datatracker.ietf.org/doc/html/rfc6901). -Known workflow errors, that we know we need to handle during workflow execution should be defined in -the workflow top-level 'errors' property. This property can be either a string type, meaning it can reference -a reusable JSON or Yaml definition file including the error definitions, or it can have an array type where you can -define these checked errors in-line in your workflow definition. +When an error arises during the execution of a workflow, whether it's at the level of an action or a state, the Error Source becomes instrumental in identifying the specific component within the workflow where the error originated. This granular identification is essential for efficient debugging and troubleshooting, as it allows developers to swiftly locate and address the root cause of the error. -Here is an example of such a definition for both cases: +By leveraging the Error Source, developers can streamline the error-handling process, facilitating quicker resolution of issues and enhancing the overall reliability and robustness of the workflow. -1. Referencing a reusable JSON/Yaml error definition file: +#### Error Handling Strategies - - - - - - - - - -
JSONYAML
+In ServerlessWorkflow, you have the flexibility to define error handling strategies using error handlers, policies, and outcome definitions. -```json -{ -"errors": "file://documents/reusable/errors.json" -} -``` +Errors can be configured at both the state and action levels, allowing you to tailor error handling to specific components within your workflow. - +When choosing an error handling strategy, consider your workflow requirements and strike a balance between simplicity, maintainability, and flexibility. Choose the approach that best fits the needs of your workflow to ensure effective error management. -```yaml -errors: file://documents/reusable/errors.json -``` +##### Inline Error Handling -
- -2. Defining workflow errors in-line: +The most basic method involves configuring the onErrors property directly within a state or an action and adding an inline handler. While suitable for specific scenarios, this approach should be used sparingly as it may lead to code duplication and reduced maintainability. @@ -5263,63 +5730,46 @@ errors: file://documents/reusable/errors.json ```json { -"errors": [ - { - "name": "Service not found error", - "code": "404", - "description": "Server has not found anything matching the provided service endpoint information" - } -] + "actions": [ + { + "name": "my-action", + "functionRef": "my-function", + "onErrors": [ + { + "when": [ + { + "status": 503 + } + ], + "retry": "retry-five-times" + } + ] + } + ] } + ```
```yaml -errors: - - name: Service not found error - code: '404' - description: Server has not found anything matching the provided service endpoint - information +actions: + - name: my-action + functionRef: my-function + onErrors: + - when: + - status: 503 + retry: retry-five-times ```
-These defined errors can then be referenced by their unique name in both states `onErrors` definitions as well as in -actions `nonRetryableErrors` and `retryableErrors` properties. - -### Action retries - -Retries allow workflows to deal with intermittent failures of services they are trying to invoke. -In addition, retries allow workflows to continue (not fail) execution and allow us to fix possible errors with invoked -services and continue execution after they are fixed. -Retries are important for both short-lived and long-lived workflows, as well as in both stateless and stateful -scenarios. - -Serverless workflow supports two distinct ways of defining retries: -1. Retrying on specified known (checked) errors. -2. Automatic retrying on both known (checked) and not-known (unchecked) errors. - -Which retry option the workflow should use by default is defined via the workflow top-level `autoRetries` property. -By default, the value of the `autoRetries` is set to `false`, meaning that retry option 1) is used by default. -You can enable automatic retrying (option 2) by setting `autoRetries` to `true`. - -Regardless of the chosen retries option, note that workflows in general should be designed to not fail. -Workflows should be able to recover from intermittent failures. +##### Error Handler Reference -The next sections provide more details to each action retry option. - -#### Retry actions on known errors - -This is the default option when the workflow top-level `autoRetries` property is not specified or is set to `false`. -This retry options is suited for stateless / short-running workflows where retries should be performed when specifically -wanted. Note that in this scenario when unknown (unchecked) errors happen during action execution (service invocation), -workflow execution should fail. - -Let's take a look at an example. To start, let's define a workflow top-level `retries` definition: +A more structured approach is to reference a pre-configured, reusable error handler. However, in most cases, it's recommended to reference an error policy instead, for improved maintainability and consistency. @@ -5331,40 +5781,90 @@ Let's take a look at an example. To start, let's define a workflow top-level `re ```json { -"retries": [ - { - "name": "first-retry-strategy", - "delay": "PT1M", - "maxAttempts": 5 + "errors": { + "definitions": [ + { + "name": "service-not-available-error", + "type": "https://serverlessworkflow.io/spec/errors/communication", + "status": 503, + "title": "Service Not Available", + "detail": "Failed to contact service, even after multiple retries" + } + ], + "handlers": [ + { + "name": "handle-503", + "when": [ + { + "status": 503 + } + ], + "retry": "retry-five-times", + "then": { + "throw": { + "refName": "service-not-available-error" + } + } + } + ] }, - { - "name": "second-retry-strategy", - "delay": "PT10M", - "maxAttempts": 10 - } -] + "states": [ + { + "name": "my-state", + "type": "operation", + "actions": [ + { + "name": "my-action", + "functionRef": "my-function", + "onErrors": [ + { + "refName": "handle-503" + } + ] + } + ] + } + ] } + ```
```yaml -retries: - - name: first-retry-strategy - delay: PT1M - maxAttempts: 5 - - name: second-retry-strategy - delay: PT10M - maxAttempts: 10 - +errors: + definitions: + - name: service-not-available-error + type: https://serverlessworkflow.io/spec/errors/communication + status: 503 + title: Service Not Available + detail: Failed to contact service, even after multiple retries + handlers: + - name: handle-503 + when: + - status: 503 + retry: retry-five-times + then: + throw: + refName: service-not-available-error +states: + - name: my-state + type: operation + actions: + - name: my-action + functionRef: my-function + onErrors: + - refName: handle-503 ```
-Our `retries` definitions can be referenced by actions. For example: +##### Error Policy Reference + +The optimal approach for addressing most error handling scenarios is to reference a configurable, reusable error policy. This promotes consistency, simplifies maintenance, and enhances workflow readability. @@ -5376,210 +5876,145 @@ Our `retries` definitions can be referenced by actions. For example: ```json { - "actions": [ - { - "functionRef": "my-first-function", - "retryRef": "first-retry-strategy", - "retryableErrors": ["SomeErrorOne", "SomeErrorTwo"] - }, - { - "functionRef": "my-second-function", - "retryRef": "second-retry-strategy", - "retryableErrors": ["SomeErrorTwo", "SomeErrorThree"] - }, + "errors": { + "definitions": [ + { + "name": "service-not-available-error", + "type": "https://serverlessworkflow.io/spec/errors/communication", + "status": 503, + "title": "Service Not Available", + "detail": "Failed to contact service, even after multiple retries" + } + ], + "handlers": [ + { + "name": "handle-503", + "when": [ + { + "status": 503 + } + ], + "retry": "retry-five-times", + "then": { + "throw": { + "refName": "service-not-available-error" + } + } + } + ] + }, + "states": [ { - "functionRef": "my-third-function" + "name": "my-state", + "type": "operation", + "actions": [ + { + "name": "my-action", + "functionRef": "my-function", + "onErrors": [ + { + "refName": "handle-503" + } + ] + } + ] } ] } + ```
```yaml -actions: - - functionRef: my-first-function - retryRef: first-retry-strategy - nonRetryableErrors: - - SomeErrorOne - - SomeErrorTwo - - functionRef: my-second-function - retryRef: second-retry-strategy - nonRetryableErrors: - - SomeErrorTwo - - SomeErrorThree - - functionRef: my-third-function +errors: + definitions: + - name: service-not-available-error + type: https://serverlessworkflow.io/spec/errors/communication + status: 503 + title: Service Not Available + detail: Failed to contact service, even after multiple retries + handlers: + - name: handle-503 + when: + - status: 503 + retry: retry-five-times + then: + throw: + refName: service-not-available-error + policy: + - name: fault-tolerance + handlers: + - refName: handle-503 +states: + - name: my-state + type: operation + actions: + - name: my-action + functionRef: my-function + onErrors: fault-tolerance ```
-Each action can define the retry strategy it wants to use. If it does not define one, the action is in this case not retries. -Actions can define a list of known errors in its `retryableErrors` array. If defined, then the action should be retried -for those errors according to the referenced retry strategy. -In our example, "MyFirstFunction" invocation should be retried according to the "FirstRetryStrategy" policy only on known errors -"SomeErrorOne" and "SomeErrorTwo". -If for a known error (defined in `retryableErrors`) the retry limit is reached and the error still persist, it can be handled in the states -`onErrors` definition. +#### Error Retries -If an unknown (unchecked) error happens during action execution, and this error is also not handled in the states `onErrors` definition, the -workflow execution should fail. +ServerlessWorkflow offers a robust error retry mechanism designed to enhance the reliability and resilience of workflows by automatically attempting to execute failed operations again under specific conditions. When an error is caught within a workflow, the retry mechanism is activated, providing an opportunity to retry the failed operation. This retry behavior is configured using the `retry` property within the [error handling definition](#error-handler-definition). -#### Automatic retries on known and unknown errors +The retry mechanism provides several benefits to workflow developers. Firstly, it improves reliability by automatically retrying failed operations, thereby reducing the likelihood of transient errors causing workflow failures. Additionally, it enhances the resilience of workflows by enabling them to recover from temporary issues or transient faults in the underlying systems, ensuring continuous execution even in the face of occasional errors. Moreover, the built-in retry capabilities simplify error handling logic, eliminating the need for manual implementation of complex retry mechanisms. This streamlines workflow development and maintenance, making it easier for developers to manage and troubleshoot error scenarios effectively. -This is the option used when the workflow top-level `autoRetries` property is set to `true`. -Automatic retries are well suited to long-running and stateful workflow orchestrations. It allows workflows -to recover from failures thus providing more resilience. There is a possible cost associated with automatic retries -in terms of resource and computing power utilization. +In summary, ServerlessWorkflow's error retry mechanism offers a comprehensive solution for handling errors during workflow execution, providing improved reliability, enhanced resilience, and simplified error handling logic. By automatically retrying failed operations under specific conditions, it ensures smoother workflow execution and minimizes the impact of errors on overall system performance. +ServerlessWorkflow offers a robust error retry mechanism to handle errors that occur during workflow execution. This retry mechanism is designed to enhance the reliability and resilience of workflows by automatically attempting to execute failed operations again under certain conditions. -With this retries option, action executions should be retried automatically for both known (checked) as well as unknown (unchecked) -errors. This means that you do not have to define a retry strategy for actions for them to have retried, it's included by default. -Users can still define a custom retry strategy for each action via the `retryRef` property. +##### Retry Policy Execution -If a retry strategy is not defined, a default retry strategy should be used. -Runtime implementations can define their own default retry strategy. Serverless Workflow recommends the following settings: +Upon encountering a defined error, if a retry policy is defined, the workflow runtime will initiate a retry attempt according to the specified policy. The [error source](#error-source), whether it be an action or a state, will be retried based on the configured policy. -* `maxAttempts` to be `unlimited`, meaning that the action should be retried indefinitely until successful. -* `delay` to be set to one second, meaning that there is a one second delay between action retries. -* `multiplier` to be set to two meaning that the delay should be multiplied by two for each retry attempt. +##### Retry Behavior -Runtimes should document their default retry strategy to users, so it's clear which -property values they are using for the default. +During each retry attempt, the workflow runtime will make another attempt to execute the operation that resulted in the error. If the retry attempt is successful, the workflow will continue execution as if the error never occurred, seamlessly progressing through the workflow. -Actions can define for which known (checked) errors they should not be retried for. -This is done via the actions `nonRetryableErrors` property. If a known error happens during action execution -which is included in the `nonRetryableErrors` property array, that action should not be retried and the error -then should be handled in the workflow states `onErrors` property. +##### Retry Exhaustion -Let's take a look at an examples of defining retries when using the automatic retries option. -This example assumes that the workfow top level `autoRetries` property is set to `true`. -To start, let's define a workflow top-level `retries` definition: +If the maximum configured number of retry attempts is reached without success, the workflow runtime will execute the error outcome defined by the `then` property within the error handling definition. This outcome could involve transitioning to a specific state, triggering compensation logic, or terminating the workflow, depending on the defined error handling strategy. - - - - - - - - - -
JSONYAML
+#### Error Outcomes -```json -{ -"retries": [ - { - "name": "first-retry-strategy", - "delay": "PT1M", - "maxAttempts": 5 - }, - { - "name": "second-retry-strategy", - "delay": "PT10M", - "maxAttempts": 10 - }, - { - "name": "no-retry-strategy", - "maxAttempts": 1 - } -] -} -``` +Error outcomes in ServerlessWorkflow provide a flexible mechanism for defining the behavior of the workflow after handling errors. They enable precise error handling strategies tailored to the workflow's requirements, ensuring that errors are managed effectively and workflows can gracefully recover from unexpected situations. - +The `compensate` outcome triggers workflow compensation. This outcome allows workflows to execute compensation logic to undo any previously completed actions and restore the system to a consistent state before proceeding to the current state's outcome. It ensures that workflows can recover from errors and maintain data integrity. -```yaml -retries: - - name: first-retry-strategy - delay: PT1M - maxAttempts: 5 - - name: second-retry-strategy - delay: PT10M - maxAttempts: 10 - - name: no-retry-strategy - maxAttempts: 1 +The `end` outcome ends the workflow immediately after handling the error. This outcome is useful when errors indicate unrecoverable situations or when workflows should terminate gracefully after encountering specific errors. -``` +The `transition` outcome instructs the workflow to transition to the specified state when the error is handled. This outcome is particularly useful for redirecting the workflow to alternative paths or recovery mechanisms based on the encountered error. -
+Finally, the `throw` outcome allows workflows to rethrow the [handled error](#error-definition) or throw a new [error](#error-definition). When set to `true`, the error is rethrown as is, propagating it up the workflow hierarchy. Alternatively, the outcome can define or reference a new error to throw, potentially using runtime expressions to customize error details dynamically. -Our retry definitions can be referenced by state actions. For example: +Overall, error outcomes in ServerlessWorkflow offer a comprehensive set of options for managing errors within workflows. By defining precise error handling strategies using these outcomes, workflows can effectively handle errors, recover from failures, and maintain robustness and resilience in various execution scenarios. - - - - - - - - - -
JSONYAML
+#### Error Bubbling -```json -{ - "actions": [ - { - "functionRef": "my-first-function", - "retryRef": "first-retry-strategy", - "nonRetryableErrors": ["SomeErrorOne", "SomeErrorTwo"] - }, - { - "functionRef": "my-second-function", - "retryRef": "second-retry-strategy", - "nonRetryableErrors": ["SomeErrorTwo", "SomeErrorThree"] - }, - { - "functionRef": "my-thrid-function" - }, - { - "functionRef": "my-fourth-function", - "retryRef": "no-retry-strategy" - } - ] -} -``` - - +Error bubbling within ServerlessWorkflow describes the process by which an unhandled or rethrown error propagates or "bubbles up" from its current location to its parent component, typically the state in which it originated. This mechanism ensures that errors are managed and handled effectively within the workflow hierarchy, maintaining consistent error handling and workflow behavior. -```yaml -actions: - - functionRef: my-first-function - retryRef: first-retry-strategy - nonRetryableErrors: - - SomeErrorOne - - SomeErrorTwo - - functionRef: my-second-function - retryRef: second-retry-strategy - nonRetryableErrors: - - SomeErrorTwo - - SomeErrorThree - - functionRef: my-third-function - - functionRef: my-fourth-function - retryRef: no-retry-strategy - -``` +When an error arises within a workflow, it initially occurs at the lowest level of execution, such as within an action. If the error remains unhandled or uncaught at this level, it ascends through the workflow's structure until it reaches the parent component of the location where the error originated. If the error persists and is not addressed at the state level, it ultimately terminates the workflow. -
+The termination of the workflow due to an unhandled error at the state level serves as a means of ensuring that errors are appropriately dealt with and do not result in erroneous or inconsistent workflow behavior. By halting the workflow's execution at the point of error occurrence, ServerlessWorkflow promotes resilience and reliability, averting potential cascading failures and ensuring predictable error handling behavior. -In our example the first action named `MyFirstFunction` is going to be retried according to the `FirstRetryStrategy` -retry policy -for all errors except `SomeErrorOne` and `SomeErrorTwo`. +In essence, the error handling mechanism within ServerlessWorkflow is designed to guarantee that errors are managed and resolved effectively within workflows, thereby preventing unexpected outcomes and fostering reliability and consistency in workflow execution. -The seconds action named `MySecondFunction` is going to be retried according to the `SecondRetryStrategy` -retry policy -for all errors except `SomeErrorTwo` and `SomeErrorThree`. +#### Error Handling Best Practices -The third action named `MyThirdFunction` is going to retried according to the default runtime retry policy. -It will be retried for all errors both known (checked) as well as unknown (unckecked). +When designing error handling logic in ServerlessWorkflow, it's essential to adhere to best practices to ensure robustness and reliability: -The fourth action named `MyFourthFunction` is going to be retried according to the `DoNotRetryStrategy` -retry policy which has the `maxAttempts` property set to `1`, meaning that this action will not be retried. +- Define Clear Error Definitions: Clearly define error types and their corresponding definitions to provide meaningful information about encountered errors. +- Use Default Error Types: Whenever possible, use the predefined default error types provided by ServerlessWorkflow to ensure consistency and compatibility. +- Group Error Handlers: Group related error handlers into error policies to promote code reuse and maintainability. +- Handle Errors Gracefully: Handle errors gracefully within workflows by defining appropriate error handlers and outcome definitions to mitigate the impact of errors on workflow execution. ### Workflow Timeouts From 1f7c5ae0f2bd206ef45e137180b1b3e26bd8371b Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Thu, 15 Feb 2024 15:39:08 +0100 Subject: [PATCH 02/49] fix(Schema): Fixed the errors.json schema --- schema/errors.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schema/errors.json b/schema/errors.json index 704f01b7..3bcea396 100644 --- a/schema/errors.json +++ b/schema/errors.json @@ -203,7 +203,7 @@ "description":"The unique name of the retry definition to use" }, { - "$ref":"retries.json#/retries/definitions/retrydef", + "$ref":"retries.json#/definitions/retrydef", "description":"The inline retry definition to use" } ] From c446b759ccfa812ad79f3a53975dda8d2aba663a Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Thu, 15 Feb 2024 15:40:22 +0100 Subject: [PATCH 03/49] fix(Schema): Fixed the errors.json Signed-off-by: Charles d'Avernas --- schema/errors.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schema/errors.json b/schema/errors.json index 3bcea396..cf789cf7 100644 --- a/schema/errors.json +++ b/schema/errors.json @@ -194,7 +194,7 @@ }, "description":"References the errors not to handle. If null, and if `when` is null, all errors are caught.", "additionalItems":false, - "minItems":1 + "minItems": 1 }, "retry":{ "oneOf":[ From a032cbe219c37abd3b28c3e8bbf59a2864287253 Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Thu, 15 Feb 2024 15:42:20 +0100 Subject: [PATCH 04/49] fix(Schema): Fixed the errors.json schema Signed-off-by: Charles d'Avernas --- schema/errors.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schema/errors.json b/schema/errors.json index cf789cf7..429712f7 100644 --- a/schema/errors.json +++ b/schema/errors.json @@ -269,7 +269,7 @@ "type":"string" }, { - "$ref":"#/definitions/retryDefinition" + "$ref":"retries.json#/retries/definitions/retrydef" } ] }, From 9979afd6415c8ad0757a35cd67809ff2349d4343 Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Thu, 15 Feb 2024 15:43:39 +0100 Subject: [PATCH 05/49] Fixed the errors.json schema Signed-off-by: Charles d'Avernas --- schema/errors.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schema/errors.json b/schema/errors.json index 429712f7..fac72e0b 100644 --- a/schema/errors.json +++ b/schema/errors.json @@ -269,7 +269,7 @@ "type":"string" }, { - "$ref":"retries.json#/retries/definitions/retrydef" + "$ref":"retries.json#/definitions/retrydef" } ] }, From 117eeb0b451d9a99a0fd4cbcc10755f0fb79e342 Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Thu, 15 Feb 2024 16:10:40 +0100 Subject: [PATCH 06/49] fix(Examples): Fixed invalid examples Signed-off-by: Charles d'Avernas --- examples/new-patient-onboarding.json | 50 +++++++++++++++------------- examples/process-transactions.json | 1 - examples/provision-orders.json | 30 +++++++++++++---- 3 files changed, 50 insertions(+), 31 deletions(-) diff --git a/examples/new-patient-onboarding.json b/examples/new-patient-onboarding.json index 4c90c16d..b8785dfd 100644 --- a/examples/new-patient-onboarding.json +++ b/examples/new-patient-onboarding.json @@ -17,36 +17,21 @@ { "name": "store-patient", "functionRef": "store-patient", - "retryRef": "services-not-available-retry-strategy", - "retryableErrors": [ - "service-not-available" - ] + "onErrors": "fault-tolerance" }, { "name": "assign-doctor", "functionRef": "assign-doctor", - "retryRef": "services-not-available-retry-strategy", - "retryableErrors": [ - "service-not-available" - ] + "onErrors": "fault-tolerance" }, { "name": "schedule-appt", "functionRef": "schedule-appt", - "retryRef": "services-not-available-retry-strategy", - "retryableErrors": [ - "service-not-available" - ] + "onErrors": "fault-tolerance" } ] } ], - "onErrors": [ - { - "errorRef": "service-not-available", - "end": true - } - ], "end": true } ], @@ -71,12 +56,29 @@ "operation": "api/services.json#scheduleAppointment" } ], - "errors": [ - { - "name": "service-not-available", - "code": "503" - } - ], + "errors": { + "handlers":[ + { + "name": "handle-503-errors", + "when":[ + { + "status": 503 + } + ], + "retry": "services-not-available-retry-strategy" + } + ], + "policies":[ + { + "name": "fault-tolerance", + "handlers":[ + { + "refName": "handle-503-errors" + } + ] + } + ] + }, "retries": [ { "name": "services-not-available-retry-strategy", diff --git a/examples/process-transactions.json b/examples/process-transactions.json index c99b6ada..75bc983e 100644 --- a/examples/process-transactions.json +++ b/examples/process-transactions.json @@ -4,7 +4,6 @@ "description": "Customer Banking Transactions Workflow", "version": "1.0.0", "specVersion": "0.8", - "autoRetries": true, "constants": { "largetxamount": 5000 }, diff --git a/examples/provision-orders.json b/examples/provision-orders.json index 26f37096..dfd838ce 100644 --- a/examples/provision-orders.json +++ b/examples/provision-orders.json @@ -44,16 +44,34 @@ "transition": "apply-order", "onErrors": [ { - "errorRef": "missing-order-id", - "transition": "missing-id" + "when": [ + { + "type": "/samples/errors/missing-order-id" + } + ], + "then": { + "transition": "missing-id" + } }, { - "errorRef": "missing-order-item", - "transition": "missing-item" + "when": [ + { + "type": "/samples/errors/missing-order-item" + } + ], + "then": { + "transition": "missing-item" + } }, { - "errorRef": "missing-order-quantity", - "transition": "missing-quantity" + "when": [ + { + "type": "/samples/errors/missing-order-quantity" + } + ], + "then": { + "transition": "missing-quantity" + } } ] }, From 89d38666cb6f8a5175a699f2cedc2c1a16eb6009 Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Thu, 15 Feb 2024 16:16:55 +0100 Subject: [PATCH 07/49] fix(Schemas): Fixed the errors.json schema Signed-off-by: Charles d'Avernas --- schema/errors.json | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/schema/errors.json b/schema/errors.json index fac72e0b..ff54af98 100644 --- a/schema/errors.json +++ b/schema/errors.json @@ -112,8 +112,15 @@ "type":"string" }, "status":{ - "type":"string" - } + "oneOf": [ + { + "type":"string" + }, + { + "type": "integer" + } + ] + } }, "minProperties":1, "additionalProperties":false From b20ff0b8e60dc5f8b7d3f42e80a4be5c327af4e4 Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Thu, 15 Feb 2024 16:22:11 +0100 Subject: [PATCH 08/49] fix(Schema) Signed-off-by: Charles d'Avernas --- schema/errors.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/schema/errors.json b/schema/errors.json index ff54af98..5161b9d4 100644 --- a/schema/errors.json +++ b/schema/errors.json @@ -114,7 +114,8 @@ "status":{ "oneOf": [ { - "type":"string" + "type": "string", + "minLength": 1 }, { "type": "integer" From 0844bf52176bdf1b777c6b347f91dbf5e32a24ca Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Thu, 15 Feb 2024 16:26:14 +0100 Subject: [PATCH 09/49] fix(Schema) --- schema/errors.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/schema/errors.json b/schema/errors.json index 5161b9d4..f9367de8 100644 --- a/schema/errors.json +++ b/schema/errors.json @@ -250,7 +250,8 @@ { "properties":{ "refName":{ - "type":"string" + "type":"string", + "minLength": 1 } }, "required":[ From c113e529af0e608953aca2515118a789fddb1a7d Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Thu, 15 Feb 2024 16:45:05 +0100 Subject: [PATCH 10/49] fix(Schema) Signed-off-by: Charles d'Avernas --- .ci/validation/package-lock.json | 163 ++++--------------------------- examples/provision-orders.json | 11 --- package-lock.json | 7 +- schema/errors.json | 56 +++++++---- 4 files changed, 62 insertions(+), 175 deletions(-) diff --git a/.ci/validation/package-lock.json b/.ci/validation/package-lock.json index 761c39ab..b668349b 100644 --- a/.ci/validation/package-lock.json +++ b/.ci/validation/package-lock.json @@ -1,19 +1,18 @@ { "name": "validation", - "version": "1.0.0", + "version": "0.9.0-snapshot", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "validation", - "version": "1.0.0", + "version": "0.9.0-snapshot", "license": "ISC", "dependencies": { "ajv": "^8.12.0", "ajv-formats": "^2.1.1" }, "devDependencies": { - "@babel/preset-typescript": "^7.23.3", "@types/jest": "^29.5.10", "ts-jest": "^29.1.1", "ts-node": "^10.9.1", @@ -186,18 +185,6 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", - "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-compilation-targets": { "version": "7.22.15", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", @@ -215,34 +202,12 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.23.5.tgz", - "integrity": "sha512-QELlRWxSpgdwdJzSJn4WAhKC+hvw/AtHbbrIoncKHkhKKR/luAlKkgBDcri1EzWAo8f8VvYVryEHN4tax/V67A==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-member-expression-to-functions": "^7.23.0", - "@babel/helper-optimise-call-expression": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.20", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, "node_modules/@babel/helper-environment-visitor": { "version": "7.22.20", "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "dev": true, + "peer": true, "engines": { "node": ">=6.9.0" } @@ -252,6 +217,7 @@ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dev": true, + "peer": true, "dependencies": { "@babel/template": "^7.22.15", "@babel/types": "^7.23.0" @@ -273,23 +239,12 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz", - "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.23.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-module-imports": { "version": "7.22.15", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", "dev": true, + "peer": true, "dependencies": { "@babel/types": "^7.22.15" }, @@ -302,6 +257,7 @@ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", "dev": true, + "peer": true, "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-module-imports": "^7.22.15", @@ -316,61 +272,22 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", - "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-plugin-utils": { "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", "dev": true, + "peer": true, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz", - "integrity": "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==", - "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-member-expression-to-functions": "^7.22.15", - "@babel/helper-optimise-call-expression": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, "node_modules/@babel/helper-simple-access": { "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", - "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", - "dev": true, + "peer": true, "dependencies": { "@babel/types": "^7.22.5" }, @@ -383,6 +300,7 @@ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dev": true, + "peer": true, "dependencies": { "@babel/types": "^7.22.5" }, @@ -395,6 +313,7 @@ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", "dev": true, + "peer": true, "engines": { "node": ">=6.9.0" } @@ -413,6 +332,7 @@ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", "dev": true, + "peer": true, "engines": { "node": ">=6.9.0" } @@ -522,6 +442,7 @@ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.5.tgz", "integrity": "sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ==", "dev": true, + "peer": true, "bin": { "parser": "bin/babel-parser.js" }, @@ -599,6 +520,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz", "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==", "dev": true, + "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -708,6 +630,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz", "integrity": "sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==", "dev": true, + "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -718,65 +641,12 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz", - "integrity": "sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==", - "dev": true, - "dependencies": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-simple-access": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-typescript": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.23.5.tgz", - "integrity": "sha512-2fMkXEJkrmwgu2Bsv1Saxgj30IXZdJ+84lQcKKI7sm719oXs0BBw2ZENKdJdR1PjWndgLCEBNXJOri0fk7RYQA==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.23.5", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-typescript": "^7.23.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-typescript": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.23.3.tgz", - "integrity": "sha512-17oIGVlqz6CchO9RFYn5U6ZpWRZIngayYCtrPRSgANSwC2V1Jb+iP74nVxzzXJte8b8BYxrL1yY96xfhTBrNNQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-option": "^7.22.15", - "@babel/plugin-syntax-jsx": "^7.23.3", - "@babel/plugin-transform-modules-commonjs": "^7.23.3", - "@babel/plugin-transform-typescript": "^7.23.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/template": { "version": "7.22.15", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "dev": true, + "peer": true, "dependencies": { "@babel/code-frame": "^7.22.13", "@babel/parser": "^7.22.15", @@ -813,6 +683,7 @@ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.5.tgz", "integrity": "sha512-ON5kSOJwVO6xXVRTvOI0eOnWe7VdUcIpsovGo9U/Br4Ie4UVFQTboO2cYnDhAGU6Fp+UxSiT+pMft0SMHfuq6w==", "dev": true, + "peer": true, "dependencies": { "@babel/helper-string-parser": "^7.23.4", "@babel/helper-validator-identifier": "^7.22.20", @@ -3760,6 +3631,7 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "peer": true, "bin": { "semver": "bin/semver.js" } @@ -3977,6 +3849,7 @@ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", "dev": true, + "peer": true, "engines": { "node": ">=4" } diff --git a/examples/provision-orders.json b/examples/provision-orders.json index dfd838ce..b45f6aab 100644 --- a/examples/provision-orders.json +++ b/examples/provision-orders.json @@ -11,17 +11,6 @@ "operation": "http://myapis.org/provisioningapi.json#doProvision" } ], - "errors": [ - { - "name": "missing-order-id" - }, - { - "name": "missing-order-item" - }, - { - "name": "missing-order-quantity" - } - ], "states": [ { "name": "provision-order", diff --git a/package-lock.json b/package-lock.json index 0967ef42..07f14cde 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1 +1,6 @@ -{} +{ + "name": "specification", + "lockfileVersion": 3, + "requires": true, + "packages": {} +} diff --git a/schema/errors.json b/schema/errors.json index f9367de8..84c1e413 100644 --- a/schema/errors.json +++ b/schema/errors.json @@ -55,17 +55,20 @@ "name":{ "type":"string", "description":"The name of the error. Must follow the Serverless Workflow Naming Convention.", - "pattern":"^[a-z0-9](-?[a-z0-9])*$" + "pattern":"^[a-z0-9](-?[a-z0-9])*$", + "minLength": 1 }, "source":{ "type":"string", "description":"An RFC6901 JSON pointer that precisely identifies the component within a workflow definition (ex: funcRef, subflowRef, ...) from which the described issue originates", - "pattern":"/(\/(([^/~])|(~[01]))*)/g" + "pattern":"/(\/(([^/~])|(~[01]))*)/g", + "minLength": 1 }, "type":{ "type":"string", "description":"A RFC3986 URI reference that identifies the problem type. The RFC7807 Problem Details specification encourages that, when dereferenced, it provide human-readable documentation for the problem type (e.g., using HTML)", - "format":"uri" + "format":"uri", + "minLength": 1 }, "status":{ "type":"integer", @@ -94,7 +97,8 @@ "type":"object", "properties":{ "refName":{ - "type":"string" + "type":"string", + "minLength": 1 } }, "required":[ @@ -106,10 +110,12 @@ "type":"object", "properties":{ "instance":{ - "type":"string" + "type":"string", + "minLength": 1 }, "type":{ - "type":"string" + "type":"string", + "minLength": 1 }, "status":{ "oneOf": [ @@ -154,7 +160,8 @@ ], "properties":{ "type":{ - "type":"string" + "type":"string", + "minLength": 1 }, "status":{ "anyOf":[ @@ -162,15 +169,18 @@ "type":"integer" }, { - "type":"string" + "type":"string", + "minLength": 1 } ] }, "title":{ - "type":"string" + "type":"string", + "minLength": 1 }, "detail":{ - "type":"string" + "type":"string", + "minLength": 1 } } } @@ -184,7 +194,8 @@ "name":{ "type":"string", "description":"The unique name which is used to reference the handler.", - "pattern":"^[a-z0-9](-?[a-z0-9])*$" + "pattern":"^[a-z0-9](-?[a-z0-9])*$", + "minLength": 1 }, "when":{ "type":"array", @@ -256,7 +267,8 @@ }, "required":[ "refName" - ] + ], + "additionalProperties": false }, { "properties":{ @@ -264,18 +276,23 @@ "type":"array", "items":{ "$ref":"#/definitions/errorReference" - } + }, + "additionalItems":false, + "minItems": 1 }, "exceptWhen":{ "type":"array", "items":{ "$ref":"#/definitions/errorReference" - } + }, + "additionalItems":false, + "minItems": 1 }, "retry":{ "oneOf":[ { - "type":"string" + "type":"string", + "minLength": 1 }, { "$ref":"retries.json#/definitions/retrydef" @@ -285,7 +302,8 @@ "then":{ "$ref":"#/definitions/errorOutcomeDefinition" } - } + }, + "additionalProperties": false } ] }, @@ -295,7 +313,8 @@ "name":{ "type":"string", "description":"The unique name which is used to reference the policy.", - "pattern":"^[a-z0-9](-?[a-z0-9])*$" + "pattern":"^[a-z0-9](-?[a-z0-9])*$", + "minLength": 1 }, "handlers":{ "type":"array", @@ -303,7 +322,8 @@ "items":{ "$ref":"#/definitions/errorHandlerReference" }, - "additionalItems":false + "additionalItems":false, + "minItems": 1 } }, "required":[ From 7f7cb704dbae12243a4c8dd8f57229c45cfc0996 Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Thu, 15 Feb 2024 16:52:08 +0100 Subject: [PATCH 11/49] feat(Schema): Added "error" operation, used to throw an error Signed-off-by: Charles d'Avernas --- schema/workflow.json | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/schema/workflow.json b/schema/workflow.json index f2bd236d..7716d552 100644 --- a/schema/workflow.json +++ b/schema/workflow.json @@ -377,14 +377,14 @@ "description": "References a sub-workflow to invoke", "$ref": "#/definitions/subflowref" }, + "errorRef": { + "description": "References or defines the error to throw", + "$ref": "errors.json#/definitions/errorReference" + }, "sleep": { "description": "Defines time periods workflow execution should sleep before / after function execution", "$ref": "#/definitions/sleep" }, - "retryRef": { - "type": "string", - "description": "References a defined workflow retry definition. If not defined the default retry policy is assumed" - }, "onErrors":{ "$ref": "#/definitions/onerrors" }, @@ -417,6 +417,12 @@ "name", "subFlowRef" ] + }, + { + "required": [ + "name", + "errorRef" + ] } ] }, From acae83ee9dc2e05222eba8dda56323154da40a04 Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Thu, 15 Feb 2024 17:35:46 +0100 Subject: [PATCH 12/49] fix: Fixed Schema and Specification to address requested changes Signed-off-by: Charles d'Avernas --- specification.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/specification.md b/specification.md index 228f051b..ec66cb11 100644 --- a/specification.md +++ b/specification.md @@ -4605,10 +4605,10 @@ For more information, see the [Workflow Error Handling](#Workflow-Error-Handling | Parameter | Description | Type | Required | | --- | --- | --- | --- | | refName | The name of the error handler definition to reference. If set, all other properties are ignored. | string | no | -| when | References the errors to handle. If null or empty, and if `exceptWhen` is null or empty, all errors are caught. | array of [errorRefs](#error-reference) | no | -| exceptWhen | References the errors not to handle. If null or empty, and if `when` is null or empty, all errors are caught. | array of [errorRefs](#error-reference) | no | +| when | References the errors to handle. If null or empty, and if `exceptWhen` is null or empty, all errors are caught. | array of [error references](#error-reference) | no | +| exceptWhen | References the errors not to handle. If null or empty, and if `when` is null or empty, all errors are caught. | array of [error references](#error-reference) | no | | retry | The retry policy to use, if any. If a string, references an existing [retry definition](#retry-definition). | string or [retry definition](#retry-definition) | no | -| then | Defines the outcome, if any, when handling errors | [outcomeDef](#outcome-definition) | no | +| then | Defines the outcome, if any, when handling errors | [outcome definition](#error-outcome-definition) | no |
Click to view example definition @@ -4738,10 +4738,9 @@ By defining error policies, workflows can easily apply consistent error handling | Parameter | Description | Type | Required | | --- | --- | --- | --- | -| compensate | If `true`, triggers workflow compensation, then proceeds to the current state's outcome. | boolean | yes if `end`, `transition` and `throw` are null, otherwise no. | -| end | If `true`, ends the workflow. | boolean or [end definition](#end-definition) | yes if `compensate`, `transition` and `throw` are null, otherwise no. | -| transition | Indicates that the the workflow should transition to the specified state when the error is handled. All potential other activities are terminated. | string or [transition](#transition-definition). | yes if `compensate`, `end` and `throw` are null, otherwise no. | -| throw | Indicates that the handled error should be rethrown. If true, the error is re-thrown as is. Otherwise, configures the error to throw, potentially using runtime expressions. | boolean or [error throw definition](#error-throw-definition). | yes if `compensate`, `end` and `transition` are null, otherwise no. | +| end | If `true`, ends the workflow. | boolean or [end definition](#end-definition) | yes if `transition` and `throw` are null, otherwise no. | +| transition | Indicates that the the workflow should transition to the specified state when the error is handled. All potential other activities are terminated. | string or [transition](#transition-definition). | yes if `end` and `throw` are null, otherwise no. | +| throw | Indicates that the handled error should be rethrown. If true, the error is re-thrown as is. Otherwise, configures the error to throw, potentially using runtime expressions. | boolean or [error throw definition](#error-throw-definition). | yes if `end` and `transition` are null, otherwise no. |
Click to view example definition

From 0d067d044d1cf29445af8c54f9706157821eecd1 Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Thu, 15 Feb 2024 17:45:44 +0100 Subject: [PATCH 13/49] fix(Roadmap): Updated the roadmap Signed-off-by: Charles d'Avernas --- roadmap/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/roadmap/README.md b/roadmap/README.md index f092313d..f9add27d 100644 --- a/roadmap/README.md +++ b/roadmap/README.md @@ -37,6 +37,7 @@ _Status description:_ | ✔️| Add the new `WORKFLOW` reserved keyword to workflow expressions | | ✔️| Update `ForEach` state iteration parameter example. This parameter is an expression variable, not a JSON property | | ✔️| Add the new `rest` function type [spec doc](https://github.com/serverlessworkflow/specification/tree/main/specification.md#using-functions-for-restful-service-invocations) | +| ✔️| Refactor error handling and retries | | ✏️️| Add inline state defs in branches | | | ✏️️| Add "completedBy" functionality | | | ✏️️| Define workflow context | | From ff1d1f2ca4df5925479f57d2c30cdc1cb1f3ec27 Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Fri, 8 Mar 2024 11:56:05 +0100 Subject: [PATCH 14/49] Update schema/errors.json Co-authored-by: Ricardo Zanini <1538000+ricardozanini@users.noreply.github.com> --- schema/errors.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schema/errors.json b/schema/errors.json index 84c1e413..2026d7b4 100644 --- a/schema/errors.json +++ b/schema/errors.json @@ -1,5 +1,5 @@ { - "$id":"https://serverlessworkflow.io/schemas/0.8/errors.json", + "$id":"https://serverlessworkflow.io/schemas/0.9/errors.json", "$schema":"http://json-schema.org/draft-07/schema#", "description":"Serverless Workflow specification - errors schema", "type":"object", From a47b636e495e3e7832e87dc416860cb65a9072f1 Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Fri, 8 Mar 2024 12:02:56 +0100 Subject: [PATCH 15/49] Update specification.md Co-authored-by: Ricardo Zanini <1538000+ricardozanini@users.noreply.github.com> --- specification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification.md b/specification.md index ec66cb11..fee22e92 100644 --- a/specification.md +++ b/specification.md @@ -1956,7 +1956,7 @@ definition "id" must be a constant value. | specVersion | Serverless Workflow specification release version | string | yes | | expressionLang | Identifies the expression language used for workflow expressions. Default value is "jq" | string | no | | [timeouts](#Workflow-Timeouts) | Defines the workflow default timeout settings | string or object | no | -| [errors](#error-definitions) | Defines the workflow's error handling configuration, including error definitions, error handlers and error policies | string or [error handling configuration](#error-handling-configuration) | no | +| [errors](#error-definitions) | Defines the workflow's error handling configuration, including error definitions, error handlers, and error policies | string or [error handling configuration](#error-handling-configuration) | no | | keepActive | If `true`, workflow instances is not terminated when there are no active execution paths. Instance can be terminated with "terminate end definition" or reaching defined "workflowExecTimeout" | boolean | no | | [auth](#Auth-Definition) | Workflow authentication definitions | array or string | no | | [events](#Event-Definition) | Workflow event definitions. | array or string | no | From dad2fa0100a9058b0e1a191dae756ab2665b9d56 Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Fri, 8 Mar 2024 12:03:09 +0100 Subject: [PATCH 16/49] Update specification.md Co-authored-by: Ricardo Zanini <1538000+ricardozanini@users.noreply.github.com> --- specification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification.md b/specification.md index fee22e92..8db9cdf8 100644 --- a/specification.md +++ b/specification.md @@ -5994,7 +5994,7 @@ The `transition` outcome instructs the workflow to transition to the specified s Finally, the `throw` outcome allows workflows to rethrow the [handled error](#error-definition) or throw a new [error](#error-definition). When set to `true`, the error is rethrown as is, propagating it up the workflow hierarchy. Alternatively, the outcome can define or reference a new error to throw, potentially using runtime expressions to customize error details dynamically. -Overall, error outcomes in ServerlessWorkflow offer a comprehensive set of options for managing errors within workflows. By defining precise error handling strategies using these outcomes, workflows can effectively handle errors, recover from failures, and maintain robustness and resilience in various execution scenarios. +Overall, error outcomes in Serverless Workflow offer a comprehensive set of options for managing errors within workflows. By defining precise error handling strategies using these outcomes, workflows can effectively handle errors, recover from failures, and maintain robustness and resilience in various execution scenarios. #### Error Bubbling From 3f7bbb86ae97af4dce1dc639555e2af507dfc158 Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Fri, 8 Mar 2024 12:03:17 +0100 Subject: [PATCH 17/49] Update specification.md Co-authored-by: Ricardo Zanini <1538000+ricardozanini@users.noreply.github.com> --- specification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification.md b/specification.md index 8db9cdf8..5bd07d14 100644 --- a/specification.md +++ b/specification.md @@ -6004,7 +6004,7 @@ When an error arises within a workflow, it initially occurs at the lowest level The termination of the workflow due to an unhandled error at the state level serves as a means of ensuring that errors are appropriately dealt with and do not result in erroneous or inconsistent workflow behavior. By halting the workflow's execution at the point of error occurrence, ServerlessWorkflow promotes resilience and reliability, averting potential cascading failures and ensuring predictable error handling behavior. -In essence, the error handling mechanism within ServerlessWorkflow is designed to guarantee that errors are managed and resolved effectively within workflows, thereby preventing unexpected outcomes and fostering reliability and consistency in workflow execution. +In essence, the error handling mechanism within Serverless Workflow is designed to guarantee that errors are managed and resolved effectively within workflows, thereby preventing unexpected outcomes and fostering reliability and consistency in workflow execution. #### Error Handling Best Practices From 503c93f2bad84dc2637723a92a64c012112eac39 Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Fri, 8 Mar 2024 12:03:23 +0100 Subject: [PATCH 18/49] Update specification.md Co-authored-by: Ricardo Zanini <1538000+ricardozanini@users.noreply.github.com> --- specification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification.md b/specification.md index 5bd07d14..12737983 100644 --- a/specification.md +++ b/specification.md @@ -6008,7 +6008,7 @@ In essence, the error handling mechanism within Serverless Workflow is designed #### Error Handling Best Practices -When designing error handling logic in ServerlessWorkflow, it's essential to adhere to best practices to ensure robustness and reliability: +When designing error handling logic in Serverless Workflow, it's essential to adhere to best practices to ensure robustness and reliability: - Define Clear Error Definitions: Clearly define error types and their corresponding definitions to provide meaningful information about encountered errors. - Use Default Error Types: Whenever possible, use the predefined default error types provided by ServerlessWorkflow to ensure consistency and compatibility. From 75cbfd8136f31395403cd28f635c0d9f18bbb215 Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Fri, 8 Mar 2024 12:40:40 +0100 Subject: [PATCH 19/49] Update specification.md Co-authored-by: Ricardo Zanini <1538000+ricardozanini@users.noreply.github.com> --- specification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification.md b/specification.md index 12737983..89105b9c 100644 --- a/specification.md +++ b/specification.md @@ -4385,7 +4385,7 @@ Represents the workflow's error handling configuration, including error definiti | Parameter | Description | Type | Required | | --- | --- | --- | --- | | name | The name of the error. Must follow the [Serverless Workflow Naming Convention](#naming-convention) | string | yes | -| instance | An RFC6901 JSON pointer that precisely identifies the component within a workflow definition (ex: funcRef, subflowRef, ...) from which the described error originates. | string | yes, but is added by runtime when throwing an error | +| instance | An [RFC 6901 JSON pointer](https://datatracker.ietf.org/doc/html/rfc6901) that precisely identifies the component within a workflow definition (ex: funcRef, subflowRef, ...) from which the described error originates. | string | yes, but is added by runtime when throwing an error | | type | A RFC3986 URI reference that identifies the error type. The RFC7807 Problem Details specification encourages that, when dereferenced, it provide human-readable documentation for the error type (e.g., using HTML). The specification strongly recommends using [default error types](#error-types) for cross-compatibility concerns. | string | yes | | status | The status code generated by the origin for an occurrence of an error. Status codes are extensible by nature and runtimes are not required to understand the meaning of all defined status codes. However, for cross-compatibility concerns, the specification encourages using RFC7231 HTTP Status Codes. | string | yes | | title | A short, human-readable summary of a error type. It SHOULD NOT change from occurrence to occurrence of an error, except for purposes of localization. | string | no | From 33cc71ba60b993daf713fb44a70041998a03891b Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Fri, 8 Mar 2024 12:40:50 +0100 Subject: [PATCH 20/49] Update specification.md Co-authored-by: Ricardo Zanini <1538000+ricardozanini@users.noreply.github.com> --- specification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification.md b/specification.md index 89105b9c..523972a4 100644 --- a/specification.md +++ b/specification.md @@ -6002,7 +6002,7 @@ Error bubbling within ServerlessWorkflow describes the process by which an unhan When an error arises within a workflow, it initially occurs at the lowest level of execution, such as within an action. If the error remains unhandled or uncaught at this level, it ascends through the workflow's structure until it reaches the parent component of the location where the error originated. If the error persists and is not addressed at the state level, it ultimately terminates the workflow. -The termination of the workflow due to an unhandled error at the state level serves as a means of ensuring that errors are appropriately dealt with and do not result in erroneous or inconsistent workflow behavior. By halting the workflow's execution at the point of error occurrence, ServerlessWorkflow promotes resilience and reliability, averting potential cascading failures and ensuring predictable error handling behavior. +The termination of the workflow due to an unhandled error at the state level serves as a means of ensuring that errors are appropriately dealt with and do not result in erroneous or inconsistent workflow behavior. By halting the workflow's execution at the point of error occurrence, Serverless Workflow promotes resilience and reliability, averting potential cascading failures and ensuring predictable error handling behavior. In essence, the error handling mechanism within Serverless Workflow is designed to guarantee that errors are managed and resolved effectively within workflows, thereby preventing unexpected outcomes and fostering reliability and consistency in workflow execution. From 2b122bc88d03d42dc4b037d71a31c89fd5cc9e3a Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Fri, 8 Mar 2024 12:40:59 +0100 Subject: [PATCH 21/49] Update specification.md Co-authored-by: Ricardo Zanini <1538000+ricardozanini@users.noreply.github.com> --- specification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification.md b/specification.md index 523972a4..d5c747db 100644 --- a/specification.md +++ b/specification.md @@ -5998,7 +5998,7 @@ Overall, error outcomes in Serverless Workflow offer a comprehensive set of opti #### Error Bubbling -Error bubbling within ServerlessWorkflow describes the process by which an unhandled or rethrown error propagates or "bubbles up" from its current location to its parent component, typically the state in which it originated. This mechanism ensures that errors are managed and handled effectively within the workflow hierarchy, maintaining consistent error handling and workflow behavior. +Error bubbling within Serverless Workflow describes the process by which an unhandled or rethrown error propagates or "bubbles up" from its current location to its parent component, typically the state in which it originated. This mechanism ensures that errors are managed and handled effectively within the workflow hierarchy, maintaining consistent error handling and workflow behavior. When an error arises within a workflow, it initially occurs at the lowest level of execution, such as within an action. If the error remains unhandled or uncaught at this level, it ascends through the workflow's structure until it reaches the parent component of the location where the error originated. If the error persists and is not addressed at the state level, it ultimately terminates the workflow. From 2d9cc48ad789b89e30ffe3a58b7ac6e03bb93793 Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Fri, 17 May 2024 14:07:11 +0200 Subject: [PATCH 22/49] Updated version in all schema ids --- schema/auth.json | 2 +- schema/common.json | 2 +- schema/events.json | 2 +- schema/extensions.json | 2 +- schema/functions.json | 2 +- schema/odata.json | 2 +- schema/retries.json | 2 +- schema/secrets.json | 2 +- schema/timeouts.json | 2 +- schema/workflow.json | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/schema/auth.json b/schema/auth.json index 5a651988..d949e7c4 100644 --- a/schema/auth.json +++ b/schema/auth.json @@ -1,5 +1,5 @@ { - "$id": "https://serverlessworkflow.io/schemas/0.8/auth.json", + "$id": "https://serverlessworkflow.io/schemas/0.9/auth.json", "$schema": "http://json-schema.org/draft-07/schema#", "description": "Serverless Workflow specification - auth schema", "type": "object", diff --git a/schema/common.json b/schema/common.json index 5a3593e1..4322f834 100644 --- a/schema/common.json +++ b/schema/common.json @@ -1,5 +1,5 @@ { - "$id": "https://serverlessworkflow.io/schemas/0.8/common.json", + "$id": "https://serverlessworkflow.io/schemas/0.9/common.json", "$schema": "http://json-schema.org/draft-07/schema#", "description": "Serverless Workflow specification - common schema", "type": "object", diff --git a/schema/events.json b/schema/events.json index 9c20f8de..1365c04f 100644 --- a/schema/events.json +++ b/schema/events.json @@ -1,5 +1,5 @@ { - "$id": "https://serverlessworkflow.io/schemas/0.8/events.json", + "$id": "https://serverlessworkflow.io/schemas/0.9/events.json", "$schema": "http://json-schema.org/draft-07/schema#", "description": "Serverless Workflow specification - events schema", "type": "object", diff --git a/schema/extensions.json b/schema/extensions.json index e04599cf..364b543e 100644 --- a/schema/extensions.json +++ b/schema/extensions.json @@ -1,5 +1,5 @@ { - "$id": "https://serverlessworkflow.io/schemas/0.8/extensions.json", + "$id": "https://serverlessworkflow.io/schemas/0.9/extensions.json", "$schema": "http://json-schema.org/draft-07/schema#", "description": "Serverless Workflow specification - extensions schema", "type": "object", diff --git a/schema/functions.json b/schema/functions.json index 0b3448d9..4572f9f4 100644 --- a/schema/functions.json +++ b/schema/functions.json @@ -1,5 +1,5 @@ { - "$id": "https://serverlessworkflow.io/schemas/0.8/functions.json", + "$id": "https://serverlessworkflow.io/schemas/0.9/functions.json", "$schema": "http://json-schema.org/draft-07/schema#", "description": "Serverless Workflow specification - functions schema", "type": "object", diff --git a/schema/odata.json b/schema/odata.json index 958cd99c..79df36ea 100644 --- a/schema/odata.json +++ b/schema/odata.json @@ -1,5 +1,5 @@ { - "$id": "https://serverlessworkflow.io/schemas/0.8/odata.json", + "$id": "https://serverlessworkflow.io/schemas/0.9/odata.json", "$schema": "http://json-schema.org/draft-07/schema#", "description": "Serverless Workflow specification - OData command options schema", "type": "object", diff --git a/schema/retries.json b/schema/retries.json index fe77f3df..74cade86 100644 --- a/schema/retries.json +++ b/schema/retries.json @@ -1,5 +1,5 @@ { - "$id": "https://serverlessworkflow.io/schemas/0.8/retries.json", + "$id": "https://serverlessworkflow.io/schemas/0.9/retries.json", "$schema": "http://json-schema.org/draft-07/schema#", "description": "Serverless Workflow specification - retries schema", "type": "object", diff --git a/schema/secrets.json b/schema/secrets.json index dc553cc1..dec1c0c4 100644 --- a/schema/secrets.json +++ b/schema/secrets.json @@ -1,5 +1,5 @@ { - "$id": "https://serverlessworkflow.io/schemas/0.8/secrets.json", + "$id": "https://serverlessworkflow.io/schemas/0.9/secrets.json", "$schema": "http://json-schema.org/draft-07/schema#", "description": "Serverless Workflow specification - secrets schema", "type": "object", diff --git a/schema/timeouts.json b/schema/timeouts.json index 95f30ce5..30ff3c12 100644 --- a/schema/timeouts.json +++ b/schema/timeouts.json @@ -1,5 +1,5 @@ { - "$id": "https://serverlessworkflow.io/schemas/0.8/timeouts.json", + "$id": "https://serverlessworkflow.io/schemas/0.9/timeouts.json", "$schema": "http://json-schema.org/draft-07/schema#", "description": "Serverless Workflow specification - functions schema", "type": "object", diff --git a/schema/workflow.json b/schema/workflow.json index 7716d552..eec3d9d5 100644 --- a/schema/workflow.json +++ b/schema/workflow.json @@ -1,5 +1,5 @@ { - "$id": "https://serverlessworkflow.io/schemas/0.8/workflow.json", + "$id": "https://serverlessworkflow.io/schemas/0.9/workflow.json", "$schema": "http://json-schema.org/draft-07/schema#", "description": "Serverless Workflow specification - workflow schema", "type": "object", From 49013fd0b2e7bfb1e547fd1c822b091eb721ed19 Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Fri, 17 May 2024 15:12:30 +0200 Subject: [PATCH 23/49] Update specification.md Co-authored-by: Ricardo Zanini <1538000+ricardozanini@users.noreply.github.com> --- specification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification.md b/specification.md index 8c5cf977..754339fb 100644 --- a/specification.md +++ b/specification.md @@ -4462,7 +4462,7 @@ Represents the workflow's error handling configuration, including error definiti | --- | --- | --- | --- | | name | The name of the error. Must follow the [Serverless Workflow Naming Convention](#naming-convention) | string | yes | | instance | An [RFC 6901 JSON pointer](https://datatracker.ietf.org/doc/html/rfc6901) that precisely identifies the component within a workflow definition (ex: funcRef, subflowRef, ...) from which the described error originates. | string | yes, but is added by runtime when throwing an error | -| type | A RFC3986 URI reference that identifies the error type. The RFC7807 Problem Details specification encourages that, when dereferenced, it provide human-readable documentation for the error type (e.g., using HTML). The specification strongly recommends using [default error types](#error-types) for cross-compatibility concerns. | string | yes | +| type | An [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986) URI reference that identifies the error type. The [RFC 7807 Problem Details specification](https://datatracker.ietf.org/doc/html/rfc7807) encourages that, when dereferenced, it provides human-readable documentation for the error type (e.g., using HTML). The specification strongly recommends using [default error types](#error-types) for cross-compatibility concerns. | string | yes | | status | The status code generated by the origin for an occurrence of an error. Status codes are extensible by nature and runtimes are not required to understand the meaning of all defined status codes. However, for cross-compatibility concerns, the specification encourages using RFC7231 HTTP Status Codes. | string | yes | | title | A short, human-readable summary of a error type. It SHOULD NOT change from occurrence to occurrence of an error, except for purposes of localization. | string | no | | detail | A human-readable explanation specific to an occurrence of an error. | string | no | From 26557df4971e18cd714b00015e2214bc4e6628e1 Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Fri, 17 May 2024 15:13:05 +0200 Subject: [PATCH 24/49] Update specification.md Co-authored-by: Ricardo Zanini <1538000+ricardozanini@users.noreply.github.com> --- specification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification.md b/specification.md index 754339fb..77e6531f 100644 --- a/specification.md +++ b/specification.md @@ -4463,7 +4463,7 @@ Represents the workflow's error handling configuration, including error definiti | name | The name of the error. Must follow the [Serverless Workflow Naming Convention](#naming-convention) | string | yes | | instance | An [RFC 6901 JSON pointer](https://datatracker.ietf.org/doc/html/rfc6901) that precisely identifies the component within a workflow definition (ex: funcRef, subflowRef, ...) from which the described error originates. | string | yes, but is added by runtime when throwing an error | | type | An [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986) URI reference that identifies the error type. The [RFC 7807 Problem Details specification](https://datatracker.ietf.org/doc/html/rfc7807) encourages that, when dereferenced, it provides human-readable documentation for the error type (e.g., using HTML). The specification strongly recommends using [default error types](#error-types) for cross-compatibility concerns. | string | yes | -| status | The status code generated by the origin for an occurrence of an error. Status codes are extensible by nature and runtimes are not required to understand the meaning of all defined status codes. However, for cross-compatibility concerns, the specification encourages using RFC7231 HTTP Status Codes. | string | yes | +| status | The status code generated by the origin for the occurrence of an error. Status codes are extensible by nature and runtimes are not required to understand the meaning of all defined status codes. However, for cross-compatibility concerns, the specification encourages using [RFC 7231 HTTP Status Codes](https://datatracker.ietf.org/doc/html/rfc7231). | string | yes | | title | A short, human-readable summary of a error type. It SHOULD NOT change from occurrence to occurrence of an error, except for purposes of localization. | string | no | | detail | A human-readable explanation specific to an occurrence of an error. | string | no | From 2e9aa9b37d79f951bf0c5bb4e4ef104df2aeb280 Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Fri, 17 May 2024 15:13:43 +0200 Subject: [PATCH 25/49] Update specification.md Co-authored-by: Ricardo Zanini <1538000+ricardozanini@users.noreply.github.com> --- specification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification.md b/specification.md index 77e6531f..e05d28bc 100644 --- a/specification.md +++ b/specification.md @@ -4464,7 +4464,7 @@ Represents the workflow's error handling configuration, including error definiti | instance | An [RFC 6901 JSON pointer](https://datatracker.ietf.org/doc/html/rfc6901) that precisely identifies the component within a workflow definition (ex: funcRef, subflowRef, ...) from which the described error originates. | string | yes, but is added by runtime when throwing an error | | type | An [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986) URI reference that identifies the error type. The [RFC 7807 Problem Details specification](https://datatracker.ietf.org/doc/html/rfc7807) encourages that, when dereferenced, it provides human-readable documentation for the error type (e.g., using HTML). The specification strongly recommends using [default error types](#error-types) for cross-compatibility concerns. | string | yes | | status | The status code generated by the origin for the occurrence of an error. Status codes are extensible by nature and runtimes are not required to understand the meaning of all defined status codes. However, for cross-compatibility concerns, the specification encourages using [RFC 7231 HTTP Status Codes](https://datatracker.ietf.org/doc/html/rfc7231). | string | yes | -| title | A short, human-readable summary of a error type. It SHOULD NOT change from occurrence to occurrence of an error, except for purposes of localization. | string | no | +| title | A short, human-readable summary of an error type. It SHOULD NOT change from occurrence to occurrence of an error, except for purposes of localization. | string | no | | detail | A human-readable explanation specific to an occurrence of an error. | string | no |

Click to view example definition From aa7f3dff1b89addf56f7e87bf53b0d36f104f7df Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Fri, 17 May 2024 15:13:57 +0200 Subject: [PATCH 26/49] Update specification.md Co-authored-by: Ricardo Zanini <1538000+ricardozanini@users.noreply.github.com> --- specification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification.md b/specification.md index e05d28bc..182331e1 100644 --- a/specification.md +++ b/specification.md @@ -4465,7 +4465,7 @@ Represents the workflow's error handling configuration, including error definiti | type | An [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986) URI reference that identifies the error type. The [RFC 7807 Problem Details specification](https://datatracker.ietf.org/doc/html/rfc7807) encourages that, when dereferenced, it provides human-readable documentation for the error type (e.g., using HTML). The specification strongly recommends using [default error types](#error-types) for cross-compatibility concerns. | string | yes | | status | The status code generated by the origin for the occurrence of an error. Status codes are extensible by nature and runtimes are not required to understand the meaning of all defined status codes. However, for cross-compatibility concerns, the specification encourages using [RFC 7231 HTTP Status Codes](https://datatracker.ietf.org/doc/html/rfc7231). | string | yes | | title | A short, human-readable summary of an error type. It SHOULD NOT change from occurrence to occurrence of an error, except for purposes of localization. | string | no | -| detail | A human-readable explanation specific to an occurrence of an error. | string | no | +| detail | A human-readable explanation specific to the occurrence of an error. | string | no |
Click to view example definition

From b2157151a96f15d40910585dbbd06490e86382e3 Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Fri, 17 May 2024 15:14:19 +0200 Subject: [PATCH 27/49] Update specification.md Co-authored-by: Ricardo Zanini <1538000+ricardozanini@users.noreply.github.com> --- specification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification.md b/specification.md index 182331e1..27a0bdde 100644 --- a/specification.md +++ b/specification.md @@ -4505,7 +4505,7 @@ detail: "The function 'my-function' timed out."

-Error definitions are [RFC7807](https://datatracker.ietf.org/doc/html/rfc7807) compliant descriptions of errors that are produced by/originating from the execution of a workflow. Runtimes use them to describe workflow related errors in a user-friendly, technology agnostic and cross-platform way. +Error definitions are [RFC 7807](https://datatracker.ietf.org/doc/html/rfc7807) compliant descriptions of errors that are produced by/originating from the execution of a workflow. Runtimes use them to describe workflow related errors in a user-friendly, technology agnostic, and cross-platform way. Property `instance` identifies the component within a workflow definition from which the described error originates. It is set by runtimes when throwing an error. From 42cb30aa0f9dd66a7041246ff50871a33853b60d Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Fri, 17 May 2024 15:14:41 +0200 Subject: [PATCH 28/49] Update specification.md Co-authored-by: Ricardo Zanini <1538000+ricardozanini@users.noreply.github.com> --- specification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification.md b/specification.md index 27a0bdde..3c91d266 100644 --- a/specification.md +++ b/specification.md @@ -4509,7 +4509,7 @@ Error definitions are [RFC 7807](https://datatracker.ietf.org/doc/html/rfc7807) Property `instance` identifies the component within a workflow definition from which the described error originates. It is set by runtimes when throwing an error. -For example, in the above definition, the source '/states/0/actions/0' indicates that the error originates from the execution of the first action of the first state of the workflow definitions. +For example, in the above definition, the source `/states/0/actions/0` indicates that the error originates from the execution of the first action of the first state of the workflow definitions. This helps both users and implementers to describe and communicate about origins of errors without technical, technology/platform specific knowledge or understanding. Property `type` is an URI used to identify the type of the error. From f808d079a4163c500ec8d7bcd472b7ebccf9a3a1 Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Fri, 17 May 2024 15:15:17 +0200 Subject: [PATCH 29/49] Update specification.md Co-authored-by: Ricardo Zanini <1538000+ricardozanini@users.noreply.github.com> --- specification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification.md b/specification.md index 3c91d266..c2b230c9 100644 --- a/specification.md +++ b/specification.md @@ -4520,7 +4520,7 @@ Property `status` identifies the error's status code. Properties `title` and `detail` are used to provide additional information about the error. -Note that an error definition should **NOT** carry any implementation-specific information such as stack traces or code references: its purpose is to provide users a consistent, human-readable description of an error. +Note that an error definition should **NOT** carry any implementation-specific information such as stack traces or code references: its purpose is to provide users with a consistent, human-readable description of an error. ##### Error Types From 2c84916dcb046d3f1a07e5e37f7f7c6358d75991 Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Fri, 17 May 2024 15:15:39 +0200 Subject: [PATCH 30/49] Update specification.md Co-authored-by: Ricardo Zanini <1538000+ricardozanini@users.noreply.github.com> --- specification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification.md b/specification.md index c2b230c9..08c0bb69 100644 --- a/specification.md +++ b/specification.md @@ -4510,7 +4510,7 @@ Error definitions are [RFC 7807](https://datatracker.ietf.org/doc/html/rfc7807) Property `instance` identifies the component within a workflow definition from which the described error originates. It is set by runtimes when throwing an error. For example, in the above definition, the source `/states/0/actions/0` indicates that the error originates from the execution of the first action of the first state of the workflow definitions. -This helps both users and implementers to describe and communicate about origins of errors without technical, technology/platform specific knowledge or understanding. +This helps both users and implementers to describe and communicate the origins of errors without technical, technology/platform-specific knowledge or understanding. Property `type` is an URI used to identify the type of the error. **For cross-compatibility concerns, the specification strongly encourage using the [default types](#default-error-types).** From fbb7791c0a13a9854de9a0096451ee3ae74fb330 Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Fri, 17 May 2024 15:15:59 +0200 Subject: [PATCH 31/49] Update specification.md Co-authored-by: Ricardo Zanini <1538000+ricardozanini@users.noreply.github.com> --- specification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification.md b/specification.md index 08c0bb69..7bc23a77 100644 --- a/specification.md +++ b/specification.md @@ -4512,7 +4512,7 @@ Property `instance` identifies the component within a workflow definition from w For example, in the above definition, the source `/states/0/actions/0` indicates that the error originates from the execution of the first action of the first state of the workflow definitions. This helps both users and implementers to describe and communicate the origins of errors without technical, technology/platform-specific knowledge or understanding. -Property `type` is an URI used to identify the type of the error. +Property `type` is a URI used to identify the type of the error. **For cross-compatibility concerns, the specification strongly encourage using the [default types](#default-error-types).** Property `status` identifies the error's status code. From 4dfab1a75cc3c83ba1d2a8937ade7fd64b2bce2c Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Fri, 17 May 2024 15:16:16 +0200 Subject: [PATCH 32/49] Update specification.md Co-authored-by: Ricardo Zanini <1538000+ricardozanini@users.noreply.github.com> --- specification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification.md b/specification.md index 7bc23a77..336bf0db 100644 --- a/specification.md +++ b/specification.md @@ -4513,7 +4513,7 @@ For example, in the above definition, the source `/states/0/actions/0` indicates This helps both users and implementers to describe and communicate the origins of errors without technical, technology/platform-specific knowledge or understanding. Property `type` is a URI used to identify the type of the error. -**For cross-compatibility concerns, the specification strongly encourage using the [default types](#default-error-types).** +**For cross-compatibility concerns, the specification strongly encourages using the [default types](#default-error-types).** Property `status` identifies the error's status code. **For cross-compatibility concerns, the specification strongly encourage using [HTTP Status Codes](https://datatracker.ietf.org/doc/html/rfc7231#section-6.1).** From 131207dc407f6cac76ae51da3a64592cd2f1a062 Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Fri, 17 May 2024 15:16:37 +0200 Subject: [PATCH 33/49] Update specification.md Co-authored-by: Ricardo Zanini <1538000+ricardozanini@users.noreply.github.com> --- specification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification.md b/specification.md index 336bf0db..fa1c82f8 100644 --- a/specification.md +++ b/specification.md @@ -4532,7 +4532,7 @@ Note that an error definition should **NOT** carry any implementation-specific i | [https://serverlessworkflow.io/spec/errors/authentication](#) | 401 | Errors related to authentication failures. | | [https://serverlessworkflow.io/spec/errors/authorization](#) | 403 | Errors related to unauthorized access attempts or insufficient permissions to perform certain actions within the workflow. | | [https://serverlessworkflow.io/spec/errors/timeout](#) | 408 | Errors caused by timeouts during the execution of tasks or during interactions with external services. | -| [https://serverlessworkflow.io/spec/errors/communication](#) | 500 | Errors encountered while communicating with external services, including network errors, service unavailable, or invalid responses. | +| [https://serverlessworkflow.io/spec/errors/communication](#) | 500 | Errors encountered while communicating with external services, including network errors, service unavailable, or invalid responses. | | [https://serverlessworkflow.io/spec/errors/runtime](#) | 500 | Errors occurring during the runtime execution of a workflow, including unexpected exceptions, errors related to resource allocation, or failures in handling workflow tasks. These errors typically occur during the actual execution of workflow components and may require runtime-specific handling and resolution strategies. | The specification promotes the use of default error types by runtimes and workflow authors for describing thrown [errors](#error-definition). This approach ensures consistent identification, handling, and behavior across various platforms and implementations. From b823af0bbbd6f89dc02753e8f1d0b3ac76371654 Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Fri, 17 May 2024 15:16:58 +0200 Subject: [PATCH 34/49] Update specification.md Co-authored-by: Ricardo Zanini <1538000+ricardozanini@users.noreply.github.com> --- specification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification.md b/specification.md index fa1c82f8..c873f9d5 100644 --- a/specification.md +++ b/specification.md @@ -4580,7 +4580,7 @@ status: 504 An Error Reference in a Serverless Workflow provides a means to point to specific error instances or types within the workflow definition. It serves as a convenient way to refer to errors without duplicating their definitions. -If multiple properties are set, they are considered as cumulative conditions to match an error. +If multiple properties are set, they are considered cumulative conditions to match an error. For example, the above definition is the same than saying "match errors with `type` 'https://example.com/errors#timeout' AND with `status` '504'". From 112db028d49250e84d626ac56b9aa5f343950761 Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Fri, 17 May 2024 15:17:18 +0200 Subject: [PATCH 35/49] Update specification.md Co-authored-by: Ricardo Zanini <1538000+ricardozanini@users.noreply.github.com> --- specification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification.md b/specification.md index c873f9d5..b08ab261 100644 --- a/specification.md +++ b/specification.md @@ -4582,7 +4582,7 @@ An Error Reference in a Serverless Workflow provides a means to point to specifi If multiple properties are set, they are considered cumulative conditions to match an error. -For example, the above definition is the same than saying "match errors with `type` 'https://example.com/errors#timeout' AND with `status` '504'". +For example, the above definition is the same as saying "match errors with `type` 'https://example.com/errors#timeout' AND with `status` '504'". ##### Error Handler Definition From f3a3e0cae93973dd7f5ae364bc25c19f9947a3b4 Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Fri, 17 May 2024 15:17:46 +0200 Subject: [PATCH 36/49] Update specification.md Co-authored-by: Ricardo Zanini <1538000+ricardozanini@users.noreply.github.com> --- specification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification.md b/specification.md index b08ab261..7f83fae4 100644 --- a/specification.md +++ b/specification.md @@ -4794,7 +4794,7 @@ errors: policies: - name: 'my-retry-policy' handlers: - - refName: 'handle-timeout-error' + - refName: 'handle-timeout-error' - when: - status: 503 retry: 'my-retry-policy' From bac05dc9ec4d46cefcf61e57979d51354b4c56d3 Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Fri, 17 May 2024 15:18:03 +0200 Subject: [PATCH 37/49] Update specification.md Co-authored-by: Ricardo Zanini <1538000+ricardozanini@users.noreply.github.com> --- specification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification.md b/specification.md index 7f83fae4..de9b4738 100644 --- a/specification.md +++ b/specification.md @@ -4670,7 +4670,7 @@ The `when` property defines the specific errors to handle. Allows for handling o The `exceptWhen` property defines the specified errors NOT to handle. Allows for handling all errors, excluding specific ones. -The `retry` property serves to either reference an existing retry policy or define a new one to be employed when handling specified errors within the workflow. If a retry policy is designated, the error source identified by the [error source](#error-source) will undergo retries according to the guidelines outlined in the associated [policy](#retry-definition). In the event that a retry attempt is successful, the workflow seamlessly proceeds as though the error had not transpired. However, if the maximum number of configured retry attempts is exhausted without success, the workflow proceeds to execute the error outcome stipulated by the `then` property. +The `retry` property serves to either reference an existing retry policy or define a new one to be employed when handling specified errors within the workflow. If a retry policy is designated, the error source identified by the [error source](#error-source) will undergo retries according to the guidelines outlined in the associated [policy](#retry-definition). If a retry attempt is successful, the workflow seamlessly proceeds as though the error had not transpired. However, if the maximum number of configured retry attempts is exhausted without success, the workflow proceeds to execute the error outcome stipulated by the `then` property. The `then` property defines caught errors outcome, if any. If not defined, caught errors will be considered as handled, and the execution of the workflow will continue as if the error never occured. Handled errors that are not [rethrown](#error-outcome-definition) do NOT [bubble up](#error-bubbling). From 1bbf5befea9bc498d6ce6258a253b267551d2164 Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Fri, 17 May 2024 15:18:21 +0200 Subject: [PATCH 38/49] Update specification.md Co-authored-by: Ricardo Zanini <1538000+ricardozanini@users.noreply.github.com> --- specification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification.md b/specification.md index de9b4738..9964cf91 100644 --- a/specification.md +++ b/specification.md @@ -4672,7 +4672,7 @@ The `exceptWhen` property defines the specified errors NOT to handle. Allows for The `retry` property serves to either reference an existing retry policy or define a new one to be employed when handling specified errors within the workflow. If a retry policy is designated, the error source identified by the [error source](#error-source) will undergo retries according to the guidelines outlined in the associated [policy](#retry-definition). If a retry attempt is successful, the workflow seamlessly proceeds as though the error had not transpired. However, if the maximum number of configured retry attempts is exhausted without success, the workflow proceeds to execute the error outcome stipulated by the `then` property. -The `then` property defines caught errors outcome, if any. If not defined, caught errors will be considered as handled, and the execution of the workflow will continue as if the error never occured. Handled errors that are not [rethrown](#error-outcome-definition) do NOT [bubble up](#error-bubbling). +The `then` property defines caught error outcomes, if any. If not defined, caught errors will be considered as handled, and the execution of the workflow will continue as if the error never occurred. Handled errors that are not [rethrown](#error-outcome-definition) do NOT [bubble up](#error-bubbling). For more information, see the [Workflow Error Handling](#Workflow-Error-Handling) sections. From 68d1126b9bc04ed5bb6d0b35e78e81fbfd9a48aa Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Fri, 17 May 2024 15:18:41 +0200 Subject: [PATCH 39/49] Update specification.md Co-authored-by: Ricardo Zanini <1538000+ricardozanini@users.noreply.github.com> --- specification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification.md b/specification.md index 9964cf91..85db698d 100644 --- a/specification.md +++ b/specification.md @@ -4729,7 +4729,7 @@ errors: policies: - name: 'my-retry-policy' handlers: - - refName: 'handle-timeout-error' + - refName: 'handle-timeout-error' - when: - status: 503 retry: 'my-retry-policy' From 2867d09f351f00d6c9b72a2bb29537dbe66f345c Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Fri, 17 May 2024 15:19:00 +0200 Subject: [PATCH 40/49] Update specification.md Co-authored-by: Ricardo Zanini <1538000+ricardozanini@users.noreply.github.com> --- specification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification.md b/specification.md index 85db698d..fafa2a3b 100644 --- a/specification.md +++ b/specification.md @@ -4815,7 +4815,7 @@ By defining error policies, workflows can easily apply consistent error handling | Parameter | Description | Type | Required | | --- | --- | --- | --- | | end | If `true`, ends the workflow. | boolean or [end definition](#end-definition) | yes if `transition` and `throw` are null, otherwise no. | -| transition | Indicates that the the workflow should transition to the specified state when the error is handled. All potential other activities are terminated. | string or [transition](#transition-definition). | yes if `end` and `throw` are null, otherwise no. | +| transition | Indicates that the workflow should transition to the specified state when the error is handled. All potential other activities are terminated. | string or [transition](#transition-definition). | yes if `end` and `throw` are null, otherwise no. | | throw | Indicates that the handled error should be rethrown. If true, the error is re-thrown as is. Otherwise, configures the error to throw, potentially using runtime expressions. | boolean or [error throw definition](#error-throw-definition). | yes if `end` and `transition` are null, otherwise no. |
Click to view example definition From 4bd9fcebfdbe8625afd21d73174220b17b17ea68 Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Fri, 17 May 2024 15:19:23 +0200 Subject: [PATCH 41/49] Update specification.md Co-authored-by: Ricardo Zanini <1538000+ricardozanini@users.noreply.github.com> --- specification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification.md b/specification.md index fafa2a3b..6bb6e4fc 100644 --- a/specification.md +++ b/specification.md @@ -5765,7 +5765,7 @@ Note the same can be also specified using workflow metadata, which is the prefer ### Workflow Error Handling -Error handling is a crucial aspect of any workflow system, ensuring that the workflow can gracefully handle unexpected situations or errors that may occur during its execution. In ServerlessWorkflow, error handling is a well-defined and structured process aimed at providing developers with the tools and mechanisms necessary to manage errors effectively within their workflows. +Error handling is a crucial aspect of any workflow system, ensuring that the workflow can gracefully handle unexpected situations or errors that may occur during its execution. In Serverless Workflow, error handling is a well-defined and structured process aimed at providing developers with the tools and mechanisms necessary to manage errors effectively within their workflows. #### Error Definitions From 8cdb169a92cfe1419cb01309ee7531c6e722d4b0 Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Fri, 17 May 2024 15:19:43 +0200 Subject: [PATCH 42/49] Update specification.md Co-authored-by: Ricardo Zanini <1538000+ricardozanini@users.noreply.github.com> --- specification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification.md b/specification.md index 6bb6e4fc..7d18ab10 100644 --- a/specification.md +++ b/specification.md @@ -5769,7 +5769,7 @@ Error handling is a crucial aspect of any workflow system, ensuring that the wor #### Error Definitions -[Error definitions](#error-definition) in ServerlessWorkflow follow the [RFC7807 Problem Details specification](https://datatracker.ietf.org/doc/html/rfc7807), providing a standardized format for describing errors that may occur during workflow execution. These definitions include parameters such as name, instance, type, status, title, and detail, which collectively provide a comprehensive description of the error. By adhering to this standard, errors can be described in a consistent, technology-agnostic, and human-readable manner, facilitating effective communication and resolution. +[Error definitions](#error-definition) in Serverless Workflow follow the [RFC7807 Problem Details specification](https://datatracker.ietf.org/doc/html/rfc7807), providing a standardized format for describing errors that may occur during workflow execution. These definitions include parameters such as name, instance, type, status, title, and detail, which collectively provide a comprehensive description of the error. By adhering to this standard, errors can be described in a consistent, technology-agnostic, and human-readable manner, facilitating effective communication and resolution. #### Error Types From 9f9854ddc34b5f6d9119af72ecea1151245643d7 Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Fri, 17 May 2024 15:19:57 +0200 Subject: [PATCH 43/49] Update specification.md Co-authored-by: Ricardo Zanini <1538000+ricardozanini@users.noreply.github.com> --- specification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification.md b/specification.md index 7d18ab10..74c4f787 100644 --- a/specification.md +++ b/specification.md @@ -5773,7 +5773,7 @@ Error handling is a crucial aspect of any workflow system, ensuring that the wor #### Error Types -ServerlessWorkflow defines a set of [default error types](#error-types), each identified by a unique URI reference and associated with specific status code(s). These error types cover common scenarios such as configuration errors, validation failures, authentication issues, timeouts, and runtime exceptions. By utilizing these predefined error types, workflows can maintain cross-compatibility and ensure consistent error identification and handling across different platforms and implementations. +Serverless Workflow defines a set of [default error types](#error-types), each identified by a unique URI reference and associated with specific status code(s). These error types cover common scenarios such as configuration errors, validation failures, authentication issues, timeouts, and runtime exceptions. By utilizing these predefined error types, workflows can maintain cross-compatibility and ensure consistent error identification and handling across different platforms and implementations. #### Error Source From ef42822b45621f95d6d00fa56ef3d43e3a0b01d7 Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Fri, 17 May 2024 15:20:13 +0200 Subject: [PATCH 44/49] Update specification.md Co-authored-by: Ricardo Zanini <1538000+ricardozanini@users.noreply.github.com> --- specification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification.md b/specification.md index 74c4f787..6c056efd 100644 --- a/specification.md +++ b/specification.md @@ -5793,7 +5793,7 @@ When choosing an error handling strategy, consider your workflow requirements an ##### Inline Error Handling -The most basic method involves configuring the onErrors property directly within a state or an action and adding an inline handler. While suitable for specific scenarios, this approach should be used sparingly as it may lead to code duplication and reduced maintainability. +The most basic method involves configuring the `onErrors` property directly within a state or an action and adding an inline handler. While suitable for specific scenarios, this approach should be used sparingly as it may lead to code duplication and reduced maintainability. From 48df4900a06138a56269dd2075e8fa4efa169c21 Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Fri, 17 May 2024 15:20:28 +0200 Subject: [PATCH 45/49] Update specification.md Co-authored-by: Ricardo Zanini <1538000+ricardozanini@users.noreply.github.com> --- specification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification.md b/specification.md index 6c056efd..69c16564 100644 --- a/specification.md +++ b/specification.md @@ -6039,7 +6039,7 @@ states: #### Error Retries -ServerlessWorkflow offers a robust error retry mechanism designed to enhance the reliability and resilience of workflows by automatically attempting to execute failed operations again under specific conditions. When an error is caught within a workflow, the retry mechanism is activated, providing an opportunity to retry the failed operation. This retry behavior is configured using the `retry` property within the [error handling definition](#error-handler-definition). +Serverless Workflow offers a robust error retry mechanism designed to enhance the reliability and resilience of workflows by automatically attempting to execute failed operations again under specific conditions. When an error is caught within a workflow, the retry mechanism is activated, providing an opportunity to retry the failed operation. This retry behavior is configured using the `retry` property within the [error handling definition](#error-handler-definition). The retry mechanism provides several benefits to workflow developers. Firstly, it improves reliability by automatically retrying failed operations, thereby reducing the likelihood of transient errors causing workflow failures. Additionally, it enhances the resilience of workflows by enabling them to recover from temporary issues or transient faults in the underlying systems, ensuring continuous execution even in the face of occasional errors. Moreover, the built-in retry capabilities simplify error handling logic, eliminating the need for manual implementation of complex retry mechanisms. This streamlines workflow development and maintenance, making it easier for developers to manage and troubleshoot error scenarios effectively. From cbca2346346646472a41a19e0548e428551dd457 Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Fri, 17 May 2024 15:20:43 +0200 Subject: [PATCH 46/49] Update specification.md Co-authored-by: Ricardo Zanini <1538000+ricardozanini@users.noreply.github.com> --- specification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification.md b/specification.md index 69c16564..ca98bb73 100644 --- a/specification.md +++ b/specification.md @@ -5785,7 +5785,7 @@ By leveraging the Error Source, developers can streamline the error-handling pro #### Error Handling Strategies -In ServerlessWorkflow, you have the flexibility to define error handling strategies using error handlers, policies, and outcome definitions. +In Serverless Workflow, you have the flexibility to define error handling strategies using error handlers, policies, and outcome definitions. Errors can be configured at both the state and action levels, allowing you to tailor error handling to specific components within your workflow. From be7da4b26fb2f1458812501f94759e71f93a42f7 Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Fri, 17 May 2024 15:21:06 +0200 Subject: [PATCH 47/49] Update specification.md Co-authored-by: Ricardo Zanini <1538000+ricardozanini@users.noreply.github.com> --- specification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification.md b/specification.md index ca98bb73..50880fa7 100644 --- a/specification.md +++ b/specification.md @@ -6043,7 +6043,7 @@ Serverless Workflow offers a robust error retry mechanism designed to enhance th The retry mechanism provides several benefits to workflow developers. Firstly, it improves reliability by automatically retrying failed operations, thereby reducing the likelihood of transient errors causing workflow failures. Additionally, it enhances the resilience of workflows by enabling them to recover from temporary issues or transient faults in the underlying systems, ensuring continuous execution even in the face of occasional errors. Moreover, the built-in retry capabilities simplify error handling logic, eliminating the need for manual implementation of complex retry mechanisms. This streamlines workflow development and maintenance, making it easier for developers to manage and troubleshoot error scenarios effectively. -In summary, ServerlessWorkflow's error retry mechanism offers a comprehensive solution for handling errors during workflow execution, providing improved reliability, enhanced resilience, and simplified error handling logic. By automatically retrying failed operations under specific conditions, it ensures smoother workflow execution and minimizes the impact of errors on overall system performance. +In summary, Serverless Workflow's error retry mechanism offers a comprehensive solution for handling errors during workflow execution, providing improved reliability, enhanced resilience, and simplified error handling logic. By automatically retrying failed operations under specific conditions, it ensures smoother workflow execution and minimizes the impact of errors on overall system performance. ServerlessWorkflow offers a robust error retry mechanism to handle errors that occur during workflow execution. This retry mechanism is designed to enhance the reliability and resilience of workflows by automatically attempting to execute failed operations again under certain conditions. ##### Retry Policy Execution From 17433bbaa1e06d1a4bf71f899eafaa9f6412a97d Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Fri, 17 May 2024 15:21:20 +0200 Subject: [PATCH 48/49] Update specification.md Co-authored-by: Ricardo Zanini <1538000+ricardozanini@users.noreply.github.com> --- specification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification.md b/specification.md index 50880fa7..f7fc86b7 100644 --- a/specification.md +++ b/specification.md @@ -6044,7 +6044,7 @@ Serverless Workflow offers a robust error retry mechanism designed to enhance th The retry mechanism provides several benefits to workflow developers. Firstly, it improves reliability by automatically retrying failed operations, thereby reducing the likelihood of transient errors causing workflow failures. Additionally, it enhances the resilience of workflows by enabling them to recover from temporary issues or transient faults in the underlying systems, ensuring continuous execution even in the face of occasional errors. Moreover, the built-in retry capabilities simplify error handling logic, eliminating the need for manual implementation of complex retry mechanisms. This streamlines workflow development and maintenance, making it easier for developers to manage and troubleshoot error scenarios effectively. In summary, Serverless Workflow's error retry mechanism offers a comprehensive solution for handling errors during workflow execution, providing improved reliability, enhanced resilience, and simplified error handling logic. By automatically retrying failed operations under specific conditions, it ensures smoother workflow execution and minimizes the impact of errors on overall system performance. -ServerlessWorkflow offers a robust error retry mechanism to handle errors that occur during workflow execution. This retry mechanism is designed to enhance the reliability and resilience of workflows by automatically attempting to execute failed operations again under certain conditions. +Serverless Workflow offers a robust error retry mechanism to handle errors that occur during workflow execution. This retry mechanism is designed to enhance the reliability and resilience of workflows by automatically attempting to execute failed operations again under certain conditions. ##### Retry Policy Execution From 00736849f632b66f81ddd105e37c11d0c4f39250 Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Fri, 17 May 2024 15:21:33 +0200 Subject: [PATCH 49/49] Update specification.md Co-authored-by: Ricardo Zanini <1538000+ricardozanini@users.noreply.github.com> --- specification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification.md b/specification.md index f7fc86b7..37a31837 100644 --- a/specification.md +++ b/specification.md @@ -6060,7 +6060,7 @@ If the maximum configured number of retry attempts is reached without success, t #### Error Outcomes -Error outcomes in ServerlessWorkflow provide a flexible mechanism for defining the behavior of the workflow after handling errors. They enable precise error handling strategies tailored to the workflow's requirements, ensuring that errors are managed effectively and workflows can gracefully recover from unexpected situations. +Error outcomes in Serverless Workflow provide a flexible mechanism for defining the behavior of the workflow after handling errors. They enable precise error handling strategies tailored to the workflow's requirements, ensuring that errors are managed effectively and workflows can gracefully recover from unexpected situations. The `compensate` outcome triggers workflow compensation. This outcome allows workflows to execute compensation logic to undo any previously completed actions and restore the system to a consistent state before proceeding to the current state's outcome. It ensures that workflows can recover from errors and maintain data integrity.