From 9a9581e2ea286bb8aa8653b0945ebad509a0e9d3 Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Tue, 5 Mar 2024 15:07:35 -0600 Subject: [PATCH] Trap and do basic reporting on encoding exceptions, both client and server-side --- src/pgwui_core/core.py | 30 ++++++++++++++++++++++++++++-- src/pgwui_core/exceptions.py | 7 +++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/pgwui_core/core.py b/src/pgwui_core/core.py index e08a098..41e141a 100644 --- a/src/pgwui_core/core.py +++ b/src/pgwui_core/core.py @@ -669,6 +669,25 @@ class SQLCommand(): args = attrs.field() ec = attrs.field(default=None) + def _explain_encoding_error(self, ex): + '''Return a SQLEncodingError instance + ''' + if isinstance(ex, UnicodeEncodeError): + return core_ex.SQLEncodingError( + ex, + ("Data cannot be represented in the database" + " connection's client-side character encoding"), + (f'The SQL statement is ({self.stmt}) and the data supplied' + f' is ({self.tupl})')) + if isinstance(ex, psycopg.errors.UntranslatableCharacter): + return core_ex.SQLEncodingError( + ex, + ("Data cannot be represented in the" + " character encoding of the database"), + (f'The SQL statement is ({self.stmt}) and the data supplied' + f' is ({self.tupl})')) + return ex + def execute(self, cur): ''' Execute the sql statement. @@ -682,11 +701,18 @@ class SQLCommand(): ''' try: cur.execute(self.stmt, self.args) + except UnicodeEncodeError as ex: + if self.ec is None: + raise self._explain_encoding_error(ex) + raise self.ec(self._explain_encoding_error(ex)) + except psycopg.errors.UntranslatableCharacter as ex: + if self.ec is None: + raise self._explain_encoding_error(ex) + raise self.ec(self._explain_encoding_error(ex)) except psycopg.DatabaseError as ex: if self.ec is None: raise ex - else: - raise self.ec(ex) + raise self.ec(ex) @attrs.define(slots=False) diff --git a/src/pgwui_core/exceptions.py b/src/pgwui_core/exceptions.py index 02c8af6..d6d7c2a 100644 --- a/src/pgwui_core/exceptions.py +++ b/src/pgwui_core/exceptions.py @@ -180,6 +180,13 @@ class DataInconsistencyError(SetupError): super(DataInconsistencyError, self).__init__(e, descr, detail) +class SQLEncodingError(SetupError): + '''There was an encoding error processing a SQL statement + ''' + def __init__(self, e, descr='', detail=''): + super().__init__(e, descr, detail) + + class DBError(SetupError): '''psycopg3 raised an error''' def __init__(self, pgexc, e='process your request'): -- 2.34.1