Skip to content

Commit 39bbea9

Browse files
feat: improve error handling (#140)
1 parent 0fc2f05 commit 39bbea9

File tree

13 files changed

+138
-34
lines changed

13 files changed

+138
-34
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
### Features
88

99
1. [#130](https://github.com/InfluxCommunity/influxdb3-python/pull/130): Remove org parameters from the example code because It is not mandatory in Influxdb3
10-
2. [#139](https://github.com/InfluxCommunity/influxdb3-python/pull/139): Supports environment variables with the same name like other clients
10+
2. [#139](https://github.com/InfluxCommunity/influxdb3-python/pull/139): Supports environment variables with the same name as other clients
11+
3. [#140](https://github.com/InfluxCommunity/influxdb3-python/pull/140): Query api will throw `InfluxdbClientQueryError` when receiving `ArrowException` from gRPC servers
1112

1213
## 0.12.0 [2025-03-26]
1314

Examples/handle_query_error.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
"""
2+
Demonstrates handling error when querying InfluxDB.
3+
"""
4+
import logging
5+
from config import Config
6+
from influxdb_client_3.exceptions import InfluxDB3ClientQueryError
7+
8+
import influxdb_client_3 as InfluxDBClient3
9+
10+
11+
def main() -> None:
12+
"""
13+
Main function
14+
:return:
15+
"""
16+
config = Config()
17+
logging.basicConfig(format='%(asctime)s %(message)s', level=logging.INFO)
18+
19+
client = InfluxDBClient3.InfluxDBClient3(
20+
host=config.host,
21+
token=config.token,
22+
database=config.database
23+
)
24+
25+
try:
26+
# Select from a bucket that doesn't exist
27+
client.query("Select a from cpu11")
28+
except InfluxDB3ClientQueryError as e:
29+
logging.log(logging.ERROR, e.message)
30+
31+
32+
if __name__ == "__main__":
33+
main()

influxdb_client_3/__init__.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@
44
from typing import Any
55

66
import pyarrow as pa
7+
from pyarrow import ArrowException
78

9+
from influxdb_client_3.exceptions import InfluxDB3ClientQueryError
810
from influxdb_client_3.query.query_api import QueryApi as _QueryApi, QueryApiOptionsBuilder
911
from influxdb_client_3.read_file import UploadFile
1012
from influxdb_client_3.write_client import InfluxDBClient as _InfluxDBClient, WriteOptions, Point
11-
from influxdb_client_3.write_client.client.exceptions import InfluxDBError
13+
from influxdb_client_3.exceptions import InfluxDBError
1214
from influxdb_client_3.write_client.client.write_api import WriteApi as _WriteApi, SYNCHRONOUS, ASYNCHRONOUS, \
1315
PointSettings, DefaultWriteOptions, WriteType
1416
from influxdb_client_3.write_client.domain.write_precision import WritePrecision
@@ -400,8 +402,8 @@ def query(self, query: str, language: str = "sql", mode: str = "all", database:
400402

401403
try:
402404
return self._query_api.query(query=query, language=language, mode=mode, database=database, **kwargs)
403-
except InfluxDBError as e:
404-
raise e
405+
except ArrowException as e:
406+
raise InfluxDB3ClientQueryError(f"Error while executing query: {e}")
405407

406408
async def query_async(self, query: str, language: str = "sql", mode: str = "all", database: str = None, **kwargs):
407409
"""Query data from InfluxDB asynchronously.
@@ -433,8 +435,8 @@ async def query_async(self, query: str, language: str = "sql", mode: str = "all"
433435
mode=mode,
434436
database=database,
435437
**kwargs)
436-
except InfluxDBError as e:
437-
raise e
438+
except ArrowException as e:
439+
raise InfluxDB3ClientQueryError(f"Error while executing query: {e}")
438440

439441
def close(self):
440442
"""Close the client and clean up resources."""
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# flake8: noqa
2+
3+
from .exceptions import InfluxDB3ClientQueryError, InfluxDBError, InfluxDB3ClientError

influxdb_client_3/write_client/client/exceptions.py renamed to influxdb_client_3/exceptions/exceptions.py

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,43 @@
44

55
from urllib3 import HTTPResponse
66

7-
logger = logging.getLogger('influxdb_client_3.write_client.client.exceptions')
7+
logger = logging.getLogger('influxdb_client_3.exceptions')
88

99

10-
class InfluxDBError(Exception):
10+
class InfluxDB3ClientError(Exception):
11+
"""
12+
Exception raised for errors in the InfluxDB client operations.
13+
14+
Represents errors that occur during interactions with the InfluxDB
15+
database client. This exception is a general base class for more
16+
specific client-related failures and is typically used to signal issues
17+
such as invalid queries, connection failures, or API misusage.
18+
"""
19+
pass
20+
21+
22+
# This error is for all query operations
23+
class InfluxDB3ClientQueryError(InfluxDB3ClientError):
24+
"""
25+
Represents an error that occurs when querying an InfluxDB client.
26+
27+
This class is specifically designed to handle errors originating from
28+
client queries to an InfluxDB database. It extends the general
29+
`InfluxDBClientError`, allowing more precise identification and
30+
handling of query-related issues.
31+
32+
:ivar message: Contains the specific error message describing the
33+
query error.
34+
:type message: str
35+
"""
36+
37+
def __init__(self, error_message, *args, **kwargs):
38+
super().__init__(error_message, *args, **kwargs)
39+
self.message = error_message
40+
41+
42+
# This error is for all write operations
43+
class InfluxDBError(InfluxDB3ClientError):
1144
"""Raised when a server error occurs."""
1245

1346
def __init__(self, response: HTTPResponse = None, message: str = None):

influxdb_client_3/query/query_api.py

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -162,14 +162,11 @@ def query(self, query: str, language: str, mode: str, database: str, **kwargs):
162162
It should be a ``dictionary`` of key-value pairs.
163163
:return: The query result in the specified mode.
164164
"""
165-
try:
166-
ticket, _options = self._prepare_query(query, language, database, **kwargs)
165+
ticket, _options = self._prepare_query(query, language, database, **kwargs)
167166

168-
flight_reader = self._do_get(ticket, _options)
167+
flight_reader = self._do_get(ticket, _options)
169168

170-
return self._translate_stream_reader(flight_reader, mode)
171-
except Exception as e:
172-
raise e
169+
return self._translate_stream_reader(flight_reader, mode)
173170

174171
async def query_async(self, query: str, language: str, mode: str, database: str, **kwargs):
175172
"""Query data from InfluxDB asynchronously.
@@ -187,16 +184,13 @@ async def query_async(self, query: str, language: str, mode: str, database: str,
187184
It should be a ``dictionary`` of key-value pairs.
188185
:return: The query result in the specified mode.
189186
"""
190-
try:
191-
ticket, options = self._prepare_query(query, language, database, **kwargs)
192-
loop = asyncio.get_running_loop()
193-
_flight_reader = await loop.run_in_executor(None,
194-
self._flight_client.do_get, ticket, options)
195-
return await loop.run_in_executor(None, self._translate_stream_reader,
196-
_flight_reader,
197-
mode)
198-
except Exception as e:
199-
raise e
187+
ticket, options = self._prepare_query(query, language, database, **kwargs)
188+
loop = asyncio.get_running_loop()
189+
_flight_reader = await loop.run_in_executor(None,
190+
self._flight_client.do_get, ticket, options)
191+
return await loop.run_in_executor(None, self._translate_stream_reader,
192+
_flight_reader,
193+
mode)
200194

201195
def _translate_stream_reader(self, reader: FlightStreamReader, mode: str):
202196
from influxdb_client_3 import polars as has_polars

influxdb_client_3/write_client/client/util/multiprocessing_helper.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import multiprocessing
99

1010
from influxdb_client_3.write_client import InfluxDBClient, WriteOptions
11-
from influxdb_client_3.write_client.client.exceptions import InfluxDBError
11+
from influxdb_client_3.exceptions import InfluxDBError
1212

1313
logger = logging.getLogger('influxdb_client.client.util.multiprocessing_helper')
1414

influxdb_client_3/write_client/client/write/retry.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from urllib3 import Retry
1010
from urllib3.exceptions import MaxRetryError, ResponseError
1111

12-
from influxdb_client_3.write_client.client.exceptions import InfluxDBError
12+
from influxdb_client_3.exceptions import InfluxDBError
1313

1414
logger = logging.getLogger('influxdb_client.client.write.retry')
1515

influxdb_client_3/write_client/rest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import logging
66
from typing import Dict
77

8-
from influxdb_client_3.write_client.client.exceptions import InfluxDBError
8+
from influxdb_client_3.exceptions import InfluxDBError
99
from influxdb_client_3.write_client.configuration import Configuration
1010

1111
_UTF_8_encoding = 'utf-8'

tests/test_api_client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
from influxdb_client_3.write_client._sync.api_client import ApiClient
88
from influxdb_client_3.write_client.configuration import Configuration
9-
from influxdb_client_3.write_client.client.exceptions import InfluxDBError
9+
from influxdb_client_3.exceptions import InfluxDBError
1010
from influxdb_client_3.write_client.service import WriteService
1111
from influxdb_client_3.version import VERSION
1212

0 commit comments

Comments
 (0)