tarantool / tarantool-python

Python client library for Tarantool
https://www.tarantool.io
BSD 2-Clause "Simplified" License
100 stars 48 forks source link

Support box.error #245

Closed DifferentialOrange closed 1 year ago

DifferentialOrange commented 1 year ago

setup: clarify Python versions

We run tests with Python 3.6 and newer. Python 3.5 has reached its end of life two years ago [1]. Our code already doesn't work on Python 3.5 [2].

  1. https://endoflife.date/python
  2. https://github.com/tarantool/tarantool-python/actions/runs/3243224481/jobs/5317632662

Part of #232

deps: backport dataclasses for Python 3.6

Dataclasses would be a really convenient approach to provide box.error support. They are supported in Python since 3.7, but this package make it able to introduce their support in Python 3.6 which we still support.

Part of #232

api: ConnectionPool support for Python 3.6

After backporting dataclasses, it became possible to use ConnectionPool on Python 3.6.

Follows #196

msgpack: improve unknown ext type error message

Part of #232

iproto: support errors extra information

Since Tarantool 2.4.1, iproto error responses contain extra info with backtrace. After this patch, DatabaseError would contain extra_info property, if it was provided.

Error extra information is parsed based on common encoder/decoder rules. String fields are converted to either str or bytes based on encoding mode.

  1. https://www.tarantool.io/en/doc/latest/dev_guide/internals/box_protocol/#responses-for-errors

Part of #232

msgpack: support error extension type

Tarantool supports error extension type since version 2.4.1 [1], encoding was introduced in Tarantool 2.10.0 [2]. This patch introduces the support of Tarantool error extension type in msgpack decoders and encoders.

Tarantool error extension type objects are decoded to tarantool.BoxError type. tarantool.BoxError may be encoded to Tarantool error extension type objects.

Error extension type internals are the same as errors extra information: the only difference is that extra information is encoded as a separate error dictionary field and error extension type objects is encoded as MessagePack extension type objects.

Error extension type objects are parsed based on common encoder/decoder rules. String fields are converted to either str or bytes based on encoding mode.

The only way to receive an error extension type object from Tarantool is to receive an explicitly built box.error object: either from return box.error.new(...) or a tuple with it. All errors raised within Tarantool (including those raised with box.error(...)) are encoded based on the same rules as simple errors due to backward compatibility.

It is possible to create error extension type objects with Python code, but it not likely to be really useful since most of their fields is computed on error initialization on the server side (even for custom error types):

tarantool.BoxError(
    type='ClientError',
    file='[string "                     local err = box.error.ne..."]',
    line=1,
    message='Unknown error',
    errno=0,
    errcode=0,
)
  1. https://github.com/tarantool/tarantool/issues/4398
  2. https://github.com/tarantool/tarantool/issues/6433

Closes #232

DifferentialOrange commented 1 year ago

There is some minor CI issue after rebase, I think it is still possible to review current version.

DifferentialOrange commented 1 year ago

There is some minor CI issue after rebase, I think it is still possible to review current version.

Fixed in separate PR #251 (this PR could be reviewed independently).