Page Status: updated 2022-12-14

Error handling

Page index

Introduction

A request that fails is typically returning an OperationOutcome based on the profile NLLOperationOutcome.

There are however many atypical situations when the reply may contain other types of information. It is allways tricky to detect and describe all erroneous situations that may occur, but the error handling method described below tries to summarize how to process the returned error information in a simple but proper way.

Returned information

The communication with the Swedish National Medication List is based on 3 tiers, the transport protocol HTTP, the data exchange principle REST and the information model FHIR.

This impacts on error management as the information returned describing the error depends on the tier where the error occured.

  1. First thing to check is the HTTP status, e.g. HTTP/1.0 503 Service Unavailable. The HTTP status returned is the most importent information about the outcome of the request. Anything in the 200-range indicates a success, and anything else a failure. See HTTP status codes below for more information about common HTTP status codes.
  2. Next thing is to check is what kind of data the HTTP body contains by looking at the content type header field. Content-Type: "text/html" would for example indicate that an error occured at the transport layer beacuse a FHIR response is taged as application/fhir, e.g. Content-Type: "application/fhir+json; charset=UTF-8". A non FHIR response should be treated as a system error. It is up to the caller to decide on a proper error message for the user in case of system errors.
  3. The third thing to check is what kind of FHIR-resource the response body contains. This would in most cases be either nothing, an OperationOutcome, a Bundle or the requested resource. The content depends on what the calling system has set as prefered in the Prefer header (see Managing returned content). Prefer is set to minimal if nothing is specified in the request. An error will however always result in an OperationOutcome independent of the requested outcome. An OperationOutcome is also returned if that is the requested result, but the content will differ from a failed request in such case.
  4. The last thing when it comes to errors is to check what the OperationOutcome says about the error. How to interpret the OperationOutcome is covered in the next section.

The OperationOutcome resource

OperationOutcome is a very versatile resource that can handle information in many ways. This can make it a daunting task to build a generic error handling mechanism on the receiving end. Below is a summary of the principles used by the FHIR-layer when transmitting data as an OperationOutcome to make this task a little easier. It is important to understand that the FHIR component relies on backend systems and run on top of a routing layer. The principles can therefore not be guaranteed. Known exceptions are covered further below.

In the text below, a successful request is one with an HTTP status in the 200 range. A failed request is one with an HTTP status in the 400 or 500 range.

  • issue.severity is set to one of the 4 IssueSeverity codes. In case of a failed request issues that are the cause of the failure are tagged as “error” or "fatal”. Issues tagged as “information” or “warning” are not the cause of the failure.
  • issue.code is set to one of the IssueType codes. Commonly used codes are processing, invalid and business-rule but other codes may be used as well. The code should give a good indication of the issue type in most cases, but it is not guaranteed.
  • issue.details is used except when a DetectedIssue is included. In any other case a missing detail indicates an unforeseen error, ie a system error.
  • details.coding.system points at the code system where the code is defined. This would be "http://ehalsomyndigheten.se/fhir/CodeSystem/error-codes" in most cases. For information about the value sets that are in scope see NLLOperationOutcome.
  • details.coding.version is set to the version of the code system.
  • details.coding.code contains a code that defines what the issue is about. A code is typically in the format n-nn-nnn, for example: 2-26-104.
  • details.coding.display contains the display text from the code system. The display text may however contain parameters (dynamic parts) that are populated when the issue occurs.
  • diagnostics may occur sometimes to facilitate in depth error investigations. The content may change over time without further notice.
  • expression may contain a FHIR path when the error is related to a specific element in the request. Since the FHIR layer is on top of backend systems this may not always be possible.
  • extension:DetectedIssue is used for AFF-issues (See description below). There is no "details" element in combination with a DetectedIssue.
  • No other element should be used.

The text above referes to something called AFF-issues. AFF is an abbreviation of automatic format and constitution control (sv. automatisk format- och författningskontroll). It is a special form of business rules that triggers DetectedIssues if an issue is detected. A DetectedIssue can be wrapped inside an OperationOutcome as well as in a MedicationRequest. The later is possible if the prescription is created with AFF-warnings. An AFF-error alwayes results in a failed request with status 422.

Transactions and Bundles

Bundles can be used for handling multiple resources within one transaction. In this scenario the transaction will return a successful result only if all actions in the transaction are accepted by the server. Otherwise the transaction will be rejected.

A failed transaction will result in a HTTP status in the 400 or 500 range and in one single OperationOutcome instead of a Bundle. The element OperationOutcome.issue.expression contains information about which resource and element in the request Bundle that raised the issue. See FHIR Transaction processing ruels

NB! A successfull processing of a Bundle in a transaction that results in warnings or issues will result in a HTTP status in the 200 range, and if a response body is returned it will be in the form of a Bundle. See FHIR create/update/patch/transaction

Exceptions

Routing error

Errors that occur at routing level and never reaches the FHIR component will result in a non FHIR response.

It may look like this.

HTTP/1.0 503 Service Unavailable
Connection: close
Content-Type: text/html
 
<html>
<head>
</head>
<body>
<div>
<h1>Application is not available</h1>
<p>The application is currently not serving requests at this endpoint. It may not have been started or is still starting.</p>
</body>
</html>

FHIR parsing error

The Swedish National Medication List FHIR server is based on the HAPI FHIR library. The HAPI library handles low-level communication in FHIR language. Errors detected doing so will result in an OperationOutcome that follows another structure than the one described above.

It may look like this.

HTTP/1.1 400 Bad Request
Content-Type: application/fhir+json; charset=UTF-8
 
{
"resourceType": "OperationOutcome",
"issue": [ {
"severity": "error",
"code": "processing",
"diagnostics": "Multiple values detected for non-repeatable parameter 'code'. This server is not configured to allow multiple (AND/OR) values for this param."
} ]
}

HTTP status codes

All status codes defined by the HTTP standard may occur. The list below shows the most commonly used within the Swedish National Medication List.

Status Definition Comment
200 OK Request succeeded
201 Created Request succeeded, one or more resources was created
304 Not Modified A conditional GET has been received but pre-conditions was evaluated to false
400 Bad Request The server can't process the request due to fault in client request, e.g. structural faults in request.
401 Unauthorized The request has not been applied because it lacks valid authentication credentials for the target resource. Normally invalid token or request not allowed for user role.
403 Forbidden The server could receive and interpret the request but will not fulfill it since operation is not allowed
404 Not found Referenced resource is not found.
405 Method Not Allowed The method is known by the origin server but not supported by the target resource, e.g. a DEL request which is not supported by Swedish National Medication List
409 Conflict Conflict, normally since target resource is in another state than expected
410 Gone Requested resource is no longer available at the requested uri
412 Precondition Failed Pre-conditions defined by client could not be fulfilled. Could occur on e.g. conditional update.
422 Unprocessable Entity Resource structure could not be processed, e.g. correct JSON/XML (syntax could be processed) but doesn't comply with resource definition.
500 Internal Server Error The server encountered an unexpected condition and can't process the request
501 Not Implemented The server either does not recognize the request method, or it lacks the ability to fulfil the request.
503 Service Unavailable The server is currently unable to handle the request, due to planned maintenance or e.g. temporary overload

Examples

See Operation Outcome - Reply.