From b5b5738982efc94f87d3bc44a2183ac5467bfe70 Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Sun, 30 May 2021 01:18:10 -0500 Subject: [PATCH] Trap errors when translating into the db's encoding --- src/pgwui_core/core.py | 44 +++++++++++++++++++++++++++++++----- src/pgwui_core/exceptions.py | 5 ++++ 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/src/pgwui_core/core.py b/src/pgwui_core/core.py index 4b92571..2b96da7 100644 --- a/src/pgwui_core/core.py +++ b/src/pgwui_core/core.py @@ -62,6 +62,7 @@ from wtforms import ( FileField) import psycopg2 +import psycopg2.extensions from pgwui_core.constants import ( CHECKED, @@ -988,6 +989,7 @@ class UploadData(DBData): @attr.s class ParameterExecutor(): '''Execute a parameterized pscopg2 statement + Must be mixed in with a DataLineProcessor. ''' def param_execute(self, insert_stmt, udl): try: @@ -999,6 +1001,37 @@ class ParameterExecutor(): 'Fewer columns than column headings', f'The IndexError from psycopg2 is: ({exp})', data=udl.raw) + except UnicodeEncodeError as exp: + self.raise_encoding_error(exp, udl) + + def raise_encoding_error(self, exp, udl): + errors = [] + cnt = 1 + enc = psycopg2.extensions.encodings[self.cur.connection.encoding] + for col in udl.tuples: + try: + col.encode(encoding=enc) + except UnicodeEncodeError as detailed_exp: + errors.append(core_ex.EncodingError( + udl.lineno, + ("Data cannot be represented in the database's character" + " encoding"), + (f'The data ({col}) in column' + f' {cnt} contains an un-representable bit sequence;' + ' the reported error is:'), + str(detailed_exp), + data=udl.raw)) + cnt += 1 + if errors: + raise core_ex.MultiError(errors) + raise core_ex.EncodingError( + udl.lineno, + ("Data cannot be represented in the database's character" + " encoding"), + ('Cannot discover which column contains an un-representable' + ' bit sequence, the reported error is:'), + str(exp), + data=udl.raw) class DataLineProcessor(object): @@ -1476,12 +1509,11 @@ class DBConnector(object): try: self.upload_data(processor, self.data, errors) # Let upload handler finish - try: - self.uh.cleanup() - except core_ex.MultiError as ex: - errors.extend(ex.errors) - except core_ex.UploadError as ex: - errors.append(ex) + self.uh.cleanup() + except core_ex.MultiError as ex: + errors.extend(ex.errors) + except core_ex.UploadError as ex: + errors.append(ex) finally: self.cur.close() return errors diff --git a/src/pgwui_core/exceptions.py b/src/pgwui_core/exceptions.py index 3fe4e46..8fff49d 100644 --- a/src/pgwui_core/exceptions.py +++ b/src/pgwui_core/exceptions.py @@ -250,3 +250,8 @@ class TooManyColsError(DataLineError): class TooFewColsError(DataLineError): def __init__(self, lineno, e, descr='', detail='', data=''): super().__init__(lineno, e, descr, detail, data) + + +class EncodingError(DataLineError): + def __init__(self, lineno, e, descr='', detail='', data=''): + super().__init__(lineno, e, descr, detail, data) -- 2.34.1