Submodule box.error | Tarantool

Submodule box.error

The box.error submodule can be used to work with errors in your application. For example, you can get the information about the last error raised by Tarantool or raise custom errors manually.

The difference between raising an error using box.error and a Lua’s built-in error function is that when the error reaches the client, its error code is preserved. In contrast, a Lua error would always be presented to the client as ER_PROC_LUA.

Note

To learn how to handle errors in your application, see the Handling errors section.

You can create an error object using the box.error.new() function. The created object can be passed to box.error() to raise the error. You can also raise the error using error_object:raise().

The example below shows how to create and raise the error with the specified code and reason.

local custom_error = box.error.new({ code = 500,
                                     reason = 'Internal server error' })

box.error(custom_error)
--[[
---
- error: Internal server error
...
--]]

box.error.new() provides different overloads for creating an error object with different parameters. These overloads are similar to the box.error() overloads described in the next section.

To raise an error, call the box.error() function. This function can accept the specified error parameters or an error object created using box.error.new(). In both cases, you can use box.error() to raise the following error types:

  • A custom error with the specified reason, code, and type.
  • A predefined Tarantool error.

The following box.error() overloads are available for raising a custom error:

Note

The same overloads are available for box.error.new().

In the example below, box.error() accepts a Lua table with the specified error code and reason:

box.error { code = 500,
            reason = 'Custom server error' }
--[[
---
- error: Custom server error
...
--]]

The next example shows how to specify a custom error type:

box.error { code = 500,
            reason = 'Internal server error',
            type = 'CustomInternalError' }
--[[
---
- error: Internal server error
...
--]]

When a custom type is specified, it is returned in the error_object.type attribute. When it is not specified, error_object.type returns one of the built-in errors, such as ClientError or OutOfMemory.

This example shows how to raise an error with the type and reason specified in the box.error() arguments:

box.error('CustomConnectionError', 'cannot connect to the given port')
--[[
---
- error: cannot connect to the given port
...
--]]

You can also use a format string to compose an error reason:

box.error('CustomConnectionError', '%s cannot connect to the port %u', 'client', 8080)
--[[
---
- error: client cannot connect to the port 8080
...
--]]

The box.error(code[, …]) overload raises a predefined Tarantool error specified by its identifier. The error code defines the error message format and the number of required arguments. In the example below, no arguments are passed for the box.error.READONLY error code:

box.error(box.error.READONLY)
--[[
---
- error: Can't modify data on a read-only instance
...
--]]

For the box.error.NO_SUCH_USER error code, you need to pass one argument:

box.error(box.error.NO_SUCH_USER, 'John')
--[[
---
- error: User 'John' is not found
...
--]]

box.error.CREATE_SPACE requires two arguments:

box.error(box.error.CREATE_SPACE, 'my_space', 'the space already exists')
--[[
---
- error: 'Failed to create space ''my_space'': the space already exists'
...
--]]

To get the last raised error, call box.error.last():

box.error.last()
--[[
---
- error: Internal server error
...
--]]

To get error details, call the error_object.unpack(). Error details may include an error code, type, message, and trace.

box.error.last():unpack()
--[[
---
- code: 500
  base_type: CustomError
  type: CustomInternalError
  custom_type: CustomInternalError
  message: Internal server error
  trace:
  - file: '[string "custom_error = box.error.new({ code = 500,..."]'
    line: 1
...
--]]

You can set the last error explicitly by calling box.error.set():

-- Create two errors --
local error1 = box.error.new({ code = 500, reason = 'Custom error 1' })
local error2 = box.error.new({ code = 505, reason = 'Custom error 2' })

-- Raise the first error --
box.error(error1)
--[[
---
- error: Custom error 1
...
--]]

-- Get the last error --
box.error.last()
--[[
---
- Custom error 1
...
--]]

-- Set the second error as the last error --
box.error.set(error2)
--[[
---
...
--]]

-- Get the last error --
box.error.last()
--[[
---
- Custom error 2
...
--]]

error_object provides the API for organizing errors into lists. To set and get the previous error, use the error_object:set_prev() method and error_object.prev attribute.

local base_server_error = box.error.new({ code = 500,
                                          reason = 'Base server error',
                                          type = 'BaseServerError' })
local storage_server_error = box.error.new({ code = 507,
                                             reason = 'Not enough storage',
                                             type = 'StorageServerError' })

base_server_error:set_prev(storage_server_error)
--[[
---
...
--]]

box.error(base_server_error)
--[[
---
- error: Base server error
...
--]]

box.error.last().prev:unpack()
--[[
---
- code: 507
  base_type: CustomError
  type: StorageServerError
  custom_type: StorageServerError
  message: Not enough storage
  trace:
  - file: '[string "storage_server_error = box.error.new({ code =..."]'
    line: 1
...
--]]

Cycles are not allowed for error lists:

storage_server_error:set_prev(base_server_error)
--[[
---
- error: 'builtin/error.lua:120: Cycles are not allowed'
...
--]]

Setting the previous error does not erase its own previous members:

-- e1 -> e2 -> e3 -> e4
e1:set_prev(e2)
e2:set_prev(e3)
e3:set_prev(e4)
e2:set_prev(e5)
-- Now there are two lists: e1 -> e2 -> e5 and e3 -> e4

IPROTO also supports stacked diagnostics. See details in MessagePack extensions – The ERROR type.

To clear the errors, call box.error.clear().

box.error.clear()
--[[
---
...
--]]
box.error.last()
--[[
---
- null
...
--]]

Below is a list of box.error functions and related objects.

Name Use
box.error() Raise the last error or the error defined by the specified parameters
box.error.last() Get the last raised error
box.error.clear() Clear the errors
box.error.new() Create the error but do not raise it
box.error.set() Set the specified error as the last system error explicitly
error_object An object that defines an error
Found what you were looking for?
Feedback