1010import traceback
1111from io import StringIO
1212
13+ from psycopg2 import IntegrityError , OperationalError
14+
1315from odoo import exceptions , fields , models
1416from odoo .exceptions import UserError
1517
@@ -237,6 +239,11 @@ def exchange_send(self, exchange_record):
237239 _logger .debug (
238240 "%s send failed. Marked as errored." , exchange_record .identifier
239241 )
242+ except (OperationalError , IntegrityError ):
243+ # We don't want the finally block to be executed in this case as
244+ # the cursor is already in an aborted state and any query will fail.
245+ res = "__sql_error__"
246+ raise
240247 else :
241248 # TODO: maybe the send handler should return desired message and state
242249 message = exchange_record ._exchange_status_message ("send_ok" )
@@ -248,16 +255,18 @@ def exchange_send(self, exchange_record):
248255 )
249256 res = message
250257 finally :
251- exchange_record .write (
252- {
253- "edi_exchange_state" : state ,
254- "exchange_error" : error ,
255- "exchange_error_traceback" : traceback ,
256- # FIXME: this should come from _compute_exchanged_on
257- # but somehow it's failing in send tests (in record tests it works).
258- "exchanged_on" : fields .Datetime .now (),
259- }
260- )
258+ if res != "__sql_error__" :
259+ exchange_record .write (
260+ {
261+ "edi_exchange_state" : state ,
262+ "exchange_error" : error ,
263+ "exchange_error_traceback" : traceback ,
264+ # FIXME: this should come from _compute_exchanged_on
265+ # but somehow it's failing in send tests
266+ # (in record tests it works).
267+ "exchanged_on" : fields .Datetime .now (),
268+ }
269+ )
261270 exchange_record .notify_action_complete ("send" , message = message )
262271 return res
263272
@@ -445,20 +454,27 @@ def exchange_process(self, exchange_record):
445454 error = _get_exception_msg (err )
446455 state = "input_processed_error"
447456 res = f"Error: { error } "
457+ except (OperationalError , IntegrityError ):
458+ # We don't want the finally block to be executed in this case as
459+ # the cursor is already in an aborted state and any query will fail.
460+ res = "__sql_error__"
461+ raise
448462 else :
449463 error = traceback = None
450464 state = "input_processed"
451465 finally :
452- exchange_record .write (
453- {
454- "edi_exchange_state" : state ,
455- "exchange_error" : error ,
456- "exchange_error_traceback" : traceback ,
457- # FIXME: this should come from _compute_exchanged_on
458- # but somehow it's failing in send tests (in record tests it works).
459- "exchanged_on" : fields .Datetime .now (),
460- }
461- )
466+ if res != "__sql_error__" :
467+ exchange_record .write (
468+ {
469+ "edi_exchange_state" : state ,
470+ "exchange_error" : error ,
471+ "exchange_error_traceback" : traceback ,
472+ # FIXME: this should come from _compute_exchanged_on
473+ # but somehow it's failing in send tests
474+ # (in record tests it works).
475+ "exchanged_on" : fields .Datetime .now (),
476+ }
477+ )
462478 if (
463479 state == "input_processed_error"
464480 and old_state != "input_processed_error"
@@ -506,22 +522,29 @@ def exchange_receive(self, exchange_record):
506522 state = "input_receive_error"
507523 message = exchange_record ._exchange_status_message ("receive_ko" )
508524 res = f"Input error: { error } "
525+ except (OperationalError , IntegrityError ):
526+ # We don't want the finally block to be executed in this case as
527+ # the cursor is already in an aborted state and any query will fail.
528+ res = "__sql_error__"
529+ raise
509530 else :
510531 message = exchange_record ._exchange_status_message ("receive_ok" )
511532 error = traceback = None
512533 state = "input_received"
513534 res = message
514535 finally :
515- exchange_record .write (
516- {
517- "edi_exchange_state" : state ,
518- "exchange_error" : error ,
519- "exchange_error_traceback" : traceback ,
520- # FIXME: this should come from _compute_exchanged_on
521- # but somehow it's failing in send tests (in record tests it works).
522- "exchanged_on" : fields .Datetime .now (),
523- }
524- )
536+ if res != "__sql_error__" :
537+ exchange_record .write (
538+ {
539+ "edi_exchange_state" : state ,
540+ "exchange_error" : error ,
541+ "exchange_error_traceback" : traceback ,
542+ # FIXME: this should come from _compute_exchanged_on
543+ # but somehow it's failing in send tests
544+ # (in record tests it works).
545+ "exchanged_on" : fields .Datetime .now (),
546+ }
547+ )
525548 exchange_record .notify_action_complete ("receive" , message = message )
526549 return res
527550
0 commit comments