Skip to content

Commit 301415d

Browse files
committed
fixup! [FIX] edi_core_oca: handle OperationalError and IntegrityError exceptions to prevent finally block execution in aborted transaction state
1 parent 00f2556 commit 301415d

File tree

4 files changed

+37
-6
lines changed

4 files changed

+37
-6
lines changed

edi_core_oca/models/edi_backend.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ def exchange_send(self, exchange_record):
242242
except (OperationalError, IntegrityError):
243243
# We don't want the finally block to be executed in this case as
244244
# the cursor is already in an aborted state and any query will fail.
245-
state = "sql_error"
245+
res = "__sql_error__"
246246
raise
247247
else:
248248
# TODO: maybe the send handler should return desired message and state
@@ -255,7 +255,7 @@ def exchange_send(self, exchange_record):
255255
)
256256
res = message
257257
finally:
258-
if not state == "sql_error":
258+
if res != "__sql_error__":
259259
exchange_record.write(
260260
{
261261
"edi_exchange_state": state,
@@ -457,13 +457,13 @@ def exchange_process(self, exchange_record):
457457
except (OperationalError, IntegrityError):
458458
# We don't want the finally block to be executed in this case as
459459
# the cursor is already in an aborted state and any query will fail.
460-
state = "sql_error"
460+
res = "__sql_error__"
461461
raise
462462
else:
463463
error = traceback = None
464464
state = "input_processed"
465465
finally:
466-
if state != "sql_error":
466+
if res != "__sql_error__":
467467
exchange_record.write(
468468
{
469469
"edi_exchange_state": state,
@@ -525,15 +525,15 @@ def exchange_receive(self, exchange_record):
525525
except (OperationalError, IntegrityError):
526526
# We don't want the finally block to be executed in this case as
527527
# the cursor is already in an aborted state and any query will fail.
528-
state = "sql_error"
528+
res = "__sql_error__"
529529
raise
530530
else:
531531
message = exchange_record._exchange_status_message("receive_ok")
532532
error = traceback = None
533533
state = "input_received"
534534
res = message
535535
finally:
536-
if not state == "sql_error":
536+
if res != "__sql_error__":
537537
exchange_record.write(
538538
{
539539
"edi_exchange_state": state,

edi_core_oca/tests/test_backend_input.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
44

55
from odoo_test_helper import FakeModelLoader
6+
from psycopg2 import OperationalError
67

78
from .common import EDIBackendCommonTestCase
89

@@ -78,3 +79,12 @@ def test_receive_allow_empty_file_record(self):
7879
# Check the record
7980
self.assertEqual(self.record._get_file_content(), "")
8081
self.assertRecordValues(self.record, [{"edi_exchange_state": "input_received"}])
82+
83+
def test_receive_record_with_operational_error(self):
84+
self.record.edi_exchange_state = "input_pending"
85+
with self.assertRaises(OperationalError):
86+
self.backend.with_context(
87+
test_break_receive=OperationalError("SQL error")
88+
).exchange_receive(self.record)
89+
self.assertRecordValues(self.record, [{"edi_exchange_state": "input_pending"}])
90+
self.assertFalse(self.record.exchange_error)

edi_core_oca/tests/test_backend_output.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
from freezegun import freeze_time
99
from odoo_test_helper import FakeModelLoader
10+
from psycopg2 import OperationalError
1011

1112
from odoo import fields, tools
1213
from odoo.exceptions import UserError
@@ -122,3 +123,13 @@ def test_send_not_generated_record(self):
122123
err.exception.args[0], "Record ID=%d has no file to send!" % record.id
123124
)
124125
mocked.assert_not_called()
126+
127+
def test_send_record_with_operational_error(self):
128+
self.record.write({"edi_exchange_state": "output_pending"})
129+
self.record._set_file_content("TEST %d" % self.record.id)
130+
with self.assertRaises(OperationalError):
131+
self.backend.with_context(
132+
test_break_send=OperationalError("SQL error")
133+
).exchange_send(self.record)
134+
self.assertRecordValues(self.record, [{"edi_exchange_state": "output_pending"}])
135+
self.assertFalse(self.record.exchange_error)

edi_core_oca/tests/test_backend_process.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
from freezegun import freeze_time
88
from odoo_test_helper import FakeModelLoader
9+
from psycopg2 import IntegrityError
910

1011
from odoo import fields
1112
from odoo.exceptions import UserError
@@ -103,4 +104,13 @@ def test_process_outbound_record(self):
103104
with self.assertRaises(UserError):
104105
record.action_exchange_process()
105106

107+
def test_process_record_with_integrity_error(self):
108+
self.record.write({"edi_exchange_state": "input_received"})
109+
with self.assertRaises(IntegrityError):
110+
self.backend.with_context(
111+
test_break_process=IntegrityError("SQL error")
112+
).exchange_process(self.record)
113+
self.assertRecordValues(self.record, [{"edi_exchange_state": "input_received"}])
114+
self.assertFalse(self.record.exchange_error)
115+
106116
# TODO: test ack file are processed

0 commit comments

Comments
 (0)