Querying

Throwing errors

New in 0.34

Errors are new in 0.34, which is coming soon. Preview them now by using the next tag.

Overview

In Orbital and Taxi, error handling is managed through a throw function that allows users to control the response sent back to the user.

This includes setting the error code and the response payload. Note that currently, we do not support catching errors; throwing an error is a fatal action. This will be addressed in a future release.

Throwing Errors

Errors are thrown using the throw function. The syntax for throwing an error is:

throw((ErrorType) { errorPayload })

This is actually a casting operation, casting the payload value to the defined error type. This is because Taxi does not have a concept of constructors, or object creation.

For example, given a NotAuthorizedError, defined as follows:

NotAuthorized.taxi
import com.orbitalhq.errors.Error

model NotAuthorizedError inherits Error {
  message: ErrorMessage
}

This would be thrown as follows:

throw((NotAuthorizedError) { message: "Authentication failed" })

Here, (NotAuthorizedError) is a casting statement, as Taxi does not have the concept of constructors.

Defining Errors

Errors are defined as models in Taxi. An error model must inherit from the base Error type (com.orbitalhq.errors.Error) and can include annotations to control the HTTP response code and the response body. Below are examples of how to define and use error models.

Example: NotAuthorizedError

The NotAuthorizedError is provided out-of-the-box and is defined as follows:

@ResponseCode(401)
model NotAuthorizedError inherits Error {
  message: ErrorMessage
}

To throw this error with a custom message:

throw((NotAuthorizedError) { message: "Authentication failed" })

Response Codes and Payloads

When an error is thrown, users can control the HTTP response code and the response payload using annotations.

Example: Custom Response Code

If no response code is provided, the default response code is 400. To specify a custom response code, use the @ResponseCode annotation:

Don't forget the import

Don't forget to include the import of taxi.http.ResponseCode
import taxi.http.ResponseCode

@ResponseCode(403)
model NotAuthorizedError inherits Error {
  message: ErrorMessage
}

Example: Custom Response Body

To customize the response body, use the @ResponseBody annotation:

Don't forget the import

Don't forget to include the import of taxi.http.ResponseBody
import taxi.http.ResponseBody

model BadPermissionsError inherits Error {
  @ResponseBody
  error: {
    errorCode: String
    message: String
  }
}

Thrown as follows:

throw( (BadPermissionsError) 
  { error: 
    { errorCode: 'E1234', message: "You didn't say the magic word" }
  }
)

This would generate an error as follows:

{
  "errorCode" : "E1234",
  "message" : "You didn't say the magic word"
}

Built-in errors

As part of the release in 0.34, the following errors will be provided out-of-the-box.

Error TypeDescriptionHTTP Response Code
OperationFailedErrorThrown when an operation fails to be invoked (e.g., a server returned a 4xx/5xx error).400 (Client Error)
ModelContractViolationErrorThrown when a model cannot be constructed, generally because data was missing.422 (Unprocessable Entity)
ParseErrorThrown when source content could not be parsed (e.g., malformed JSON or CSV).400 (Bad Request)
DataNotDiscoverableErrorThrown when the query asked for data, but no services could provide the requested data.404 (Not Found)
NotAuthorizedErrorThrown to indicate that a requested data attribute or service call has been rejected.403 (Forbidden)
Previous
Query lineage and observability
Next
Overview