Service activators can be used to do http calls to the backend via pure configuration.
Service Activators can also be triggered via PFE Actions.
Documentation of the configuration
The configuration of service activators is also supported by the config editor:
{
"pageId": "summary",
"onPageLeaveServiceActivators": [
{
"path": "mo-bff/contract/process",
"responseDataMapping": [
{
"responseDataExpression": "$.contractNumber",
"stateKeyExpression": "$.contractNumber"
}
]
}
]
}
By default, a failure in a service activator call results in a redirect onto the global error page of the app. A failure is defined as any HTTP error response.
In general, the error handling can be configured in these locations:
The service activator configuration supports the definition of certain errorCases
and how they should be handled.
This is done in the errorHandling attribute within the service activator configuration. The configuration itself defines an array of errorCases.
Every ErrorCase handling can define conditions that determine if it should become active or not.
The first valid errorCase
out of all configured ones is then executed.
The execution of an error case follows these steps:
errorResponseDataMapping
configured in the errorCase
. This allows it to save data from the payload of the response into the state. It works the same as the responseDataMapping
for successful service activators.actions
that are configured in the errorCase
. This makes it possible to handle more specific behavior that is not covered by the standard configuration. The result of the action, directly translates to the behavior of the error handling. If the action returns true, the behavior is the same as with the ignoreError
flag. If it returns false, the behavior is the same as with the disableErrorPageNavigation
flag. An action can also trigger a custom navigation in this case. Alternatively, it is possible to ignore the action result with the ignoreActionsResult
flag.ignoreError
flag). In this case, no further error handling is done and the service activator behaves the same as a successful one.disableErrorPageNavigation
flag). For example: If the disableErrorPageNavigation
is set for the error case of a service activator, that was triggered in the onPageLeave*
, the navigation would be aborted and the user would stay on the current page.errorPageNavigation
of the service activator is used to determine the error page to go to. This navigation works similar to a standard navigation, but is able to access the payload of the error response.errorPageNavigation
configuration, a fallback to the global error page is done.A simple example configuration for a service activator with one error case could look like this:
{
"onPageLeaveServiceActivators": [
{
"path": "errorServiceActivator",
"errorHandling": {
"errorCases": [
{
"conditions": [
{
"type": "PFE_EXPRESSION",
"value1Expression": "$.response.status",
"operator": "==",
"value2Expression": "404"
}
],
"disableErrorPageNavigation": true
}
]
}
}
]
}
In this example, the service activator runs into a 404
response.
It is triggered when the page is left (onPageLeaveServiceActivators
)
As the disableErrorPageNavigation
flag is set, the user will stay on the page and the navigation will be aborted in case of the 404
response.
errorCase
The configuration of the errorCase conditions are the same as the standard navigation conditions. They do however have a few extra gimmicks.
The state is only available under $.state
in these conditions. The error response is available under $.response
,
which means that the response body for error responses is available under $.response.error
.
The response headers are available under $.responseHeaders
The data model for this can be found here: ErrorCaseConditionsState.
They are converted into this structure: [index: string]: string[]
The background for this is, that response headers can have duplicates. So the same header could have multiple values.
An example could look like this:
Response headers:
status: 400,
statusText:'error'
error: "Bad Request",
type: "REJECTION",
type: "this is a duplicate value of the type header"
message: "Http failure response for /path: 400 error",
These response headers are then converted to the following data model and provided to the conditions:
{
"type": ["REJECTION", "this is a duplicate value of the type header"],
"anotherHeader": ["something"]
}
In this example, we only want the error case to become active, if the type
header is set, with the value REJECTION
.
If this value is not available, the error case should not become active.
This can be done with the following condition/expression:
{
"value1Expression": "$.responseHeaders.type[?(@==\"REJECTION\")]"
}
This expression checks the values of the type
header, if the value REJECTION
is present.
To clarify, the following condition would lead to the same result. The extracted valued from the expression is REJECTION
. This value is seen as truthy in the conditions.
{
"value1Expression": "$.responseHeaders.type[?(@==\"REJECTION\")]",
"operator": "==",
"value2Expression": "REJECTION"
}
A full example of a service activator call with a more complex error handling of errors could look like this:
{
"onPageLeaveServiceActivators": [
{
"path": "endpoint",
"errorCases": [
{
"conditions": [
{
"value1Expression": "$.response.status",
"operator": "==",
"value2Expression": "400"
},
{
"value1Expression": "$.responseHeaders.type[?(@==\"REJECTION\")]",
"operator": "==",
"value2Expression": "REJECTION"
}
],
"errorPageNavigation": [
{
"nextPageId": "errorPage"
}
]
},
{
"conditions": [
{
"value1Expression": "$.response.status",
"operator": "==",
"value2Expression": "400"
}
],
"disableErrorPageNavigation": true
}
]
}
]
}
This example configuration has the effect, that the user will only be navigated to the errorPage
if the 400
response also contains the type
header with the value REJECTION
.
In all other cases, the navigation is stopped and the user stays on the page.
Actions that run within an error case can also influence the result of the error handling. If one of the actions returns a negative result (false
), the error is thrown up. This has the same effect as the disableErrorPageNavigation
flag.
An example for a custom errorPageNavigation
could look like this:
{
"onPageLeaveServiceActivators": [
{
"path": "endpoint",
"errorCases": [
{
"conditions": [
{
"value1Expression": "$.response.status",
"operator": "==",
"value2Expression": "500"
}
],
"errorPageNavigation": [
{
"nextPageId": "myCustomErrorPage",
"conditions": [
{
"value1Expression": "$.response.error.thisServer",
"operator": "==",
"value2Expression": "isCrashed"
}
]
},
{
"nextPageId": "fallbackErrorPage"
}
]
}
]
}
]
}
The navigation to the myCustomErrorPage
only happens if the response body contains the text isCrashed
in the field thisServer
for the response with the status code 500.
If that is not the case, the default fallbackErrorPage
is used.
The errorPageNavigation configuration can be used to define conditions that determine the error page that should be displayed.
Example for such a configuration:
{
"navConfiguration": {
"errorPageNavigation": [
{
"nextPageId": "teapotError",
"conditions": [
{
"value1Expression": "$.response.status",
"operator": "===",
"value2Expression": "418"
}
]
},
{
"nextPageId": "defaultErrorPage",
}
]
}
}
The conditions to determine if a navigation to an error page should happen are similar to the NavOptionConfig conditions. But in difference to those, the PFE state is only available under $.state in the error page navigation conditions.
Additionally the response data is available:
$.response
$.response.status
$.response.error
$.responseHeaders
The errorResponseDataMapping
in the errorCases
configuration of a specific service activator can be used to write the error response data to the state before the error page navigation is triggered.
The user will only be able to navigate, once the service returned a non-error response
{
"path": "some-service/validate",
"serviceActivatorMethod": "POST",
"preventNavigationOnError": true,
"requestDataMapping": [
{
"requestDataExpression": "$.fieldToValidate",
"stateKeyExpression": "$.userdata.fieldToValidate"
},
{
"requestDataExpression": "$.anotherFieldToValidate",
"stateKeyExpression": "$.userdata.anotherFieldToValidate"
}
],
"responseDataMapping": [
{
"responseDataExpression": "$",
"stateKeyExpression": "$.someService.validationStatus"
}
],
"serviceActivatorErrorHandlingExcludeStatusCodes": [404, 400],
"serviceActivatorResponseStatusHandlers": [
{
"statusCode": 400,
"stateKeyExpression": "$.validationErrorData",
"stateValue": "common.validation.formatError"
},
{
"statusCode": 404,
"stateKeyExpression": "$.validationErrorData",
"stateValue": "common.validation.notFoundError"
}
]
}
While it is recommended to rely on the trigger points of the navigation flow, it is also possible to trigger service activators directly in the code.
The PfeBusinessService
provides the triggerSingleServiceActivator() for this.
It can be used like this:
this.pfeBusinessService
.triggerSingleServiceActivator('serviceActivatorID')
.then((response) => {
// The full HTTP response of the service activator is available here
})
.catch((error) => {
// The full HTTP error response of the service activator is available here
});
By default, the PFE error handling is active for every service activator. That means an automatic navigation to the error page is triggered.
It might be desirable to stay on the current page, for example if the error is supposed to be handled manually in the code of the catch block. This can be done, by disabling the navigation to the error page for the service activator in question. For example:
{
"errorServiceActivator": {
"path": "http://example.com/this-is-a-404",
"serviceActivatorMethod": "GET",
"errorHandling": {
"errorCases": [
{
"disableErrorPageNavigation": true
}
]
}
}
}