Skip to content

Commit

Permalink
[IMP] edi_oca: Split exchange error and traceback
Browse files Browse the repository at this point in the history
  • Loading branch information
HviorForgeFlow committed Jul 30, 2024
1 parent b6a69b5 commit 5ca5d36
Show file tree
Hide file tree
Showing 11 changed files with 63 additions and 30 deletions.
57 changes: 38 additions & 19 deletions edi_oca/models/edi_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,13 @@
_logger = logging.getLogger(__name__)


def _get_exception_msg():
def _get_exception_msg(exc):
if hasattr(exc, "args") and isinstance(exc.args[0], str):
return exc.args[0]
return repr(exc)


def _get_exception_traceback():
buff = StringIO()
traceback.print_exc(file=buff)
traceback_txt = buff.getvalue()
Expand Down Expand Up @@ -228,12 +234,17 @@ def exchange_generate(self, exchange_record, store=True, force=False, **kw):
message = exchange_record._exchange_status_message("generate_ok")
try:
self._validate_data(exchange_record, output)
except EDIValidationError:
error = _get_exception_msg()
except EDIValidationError as err:
traceback = _get_exception_traceback()
error = _get_exception_msg(err)
state = "validate_error"
message = exchange_record._exchange_status_message("validate_ko")
exchange_record.update(
{"edi_exchange_state": state, "exchange_error": error}
{
"edi_exchange_state": state,
"exchange_error": error,
"exchange_error_traceback": traceback,
}
)
exchange_record.notify_action_complete("generate", message=message)
return message
Expand Down Expand Up @@ -294,22 +305,24 @@ def exchange_send(self, exchange_record):
if not check:
return self._failed_output_check_send_msg()
state = exchange_record.edi_exchange_state
error = False
error = traceback = False
message = None
res = ""
try:
self._exchange_send(exchange_record)
_logger.debug("%s sent", exchange_record.identifier)
except self._send_retryable_exceptions() as err:
error = _get_exception_msg()
traceback = _get_exception_traceback()
error = _get_exception_msg(err)
_logger.debug("%s send failed. To be retried.", exchange_record.identifier)
raise RetryableJobError(
error, **exchange_record._job_retry_params()
) from err
except self._swallable_exceptions():
except self._swallable_exceptions() as err:
if self.env.context.get("_edi_send_break_on_error"):
raise
error = _get_exception_msg()
traceback = _get_exception_traceback()
error = _get_exception_msg(err)
state = "output_error_on_send"
message = exchange_record._exchange_status_message("send_ko")
res = f"Error: {error}"
Expand All @@ -319,7 +332,7 @@ def exchange_send(self, exchange_record):
else:
# TODO: maybe the send handler should return desired message and state
message = exchange_record._exchange_status_message("send_ok")
error = None
error = traceback = None
state = (
"output_sent_and_processed"
if self.output_sent_processed_auto
Expand All @@ -331,6 +344,7 @@ def exchange_send(self, exchange_record):
{
"edi_exchange_state": state,
"exchange_error": error,
"exchange_error_traceback": traceback,
# FIXME: this should come from _compute_exchanged_on
# but somehow it's failing in send tests (in record tests it works).
"exchanged_on": fields.Datetime.now(),
Expand Down Expand Up @@ -486,24 +500,26 @@ def exchange_process(self, exchange_record):
if not check:
return "Nothing to do. Likely already processed."
old_state = state = exchange_record.edi_exchange_state
error = False
error = traceback = False
message = None
try:
res = self._exchange_process(exchange_record)
except self._swallable_exceptions():
except self._swallable_exceptions() as err:
if self.env.context.get("_edi_process_break_on_error"):
raise
error = _get_exception_msg()
traceback = _get_exception_traceback()
error = _get_exception_msg(err)
state = "input_processed_error"
res = f"Error: {error}"
else:
error = None
error = traceback = None
state = "input_processed"
finally:
exchange_record.write(
{
"edi_exchange_state": state,
"exchange_error": error,
"exchange_error_traceback": traceback,
# FIXME: this should come from _compute_exchanged_on
# but somehow it's failing in send tests (in record tests it works).
"exchanged_on": fields.Datetime.now(),
Expand Down Expand Up @@ -534,7 +550,7 @@ def exchange_receive(self, exchange_record):
if not check:
return "Nothing to do. Likely already received."
state = exchange_record.edi_exchange_state
error = False
error = traceback = False
message = None
content = None
try:
Expand All @@ -543,28 +559,31 @@ def exchange_receive(self, exchange_record):
if content is not None:
exchange_record._set_file_content(content)
self._validate_data(exchange_record)
except EDIValidationError:
error = _get_exception_msg()
except EDIValidationError as err:
traceback = _get_exception_traceback()
error = _get_exception_msg(err)
state = "validate_error"
message = exchange_record._exchange_status_message("validate_ko")
res = f"Validation error: {error}"
except self._swallable_exceptions():
except self._swallable_exceptions() as err:
if self.env.context.get("_edi_receive_break_on_error"):
raise
error = _get_exception_msg()
traceback = _get_exception_traceback()
error = _get_exception_msg(err)
state = "input_receive_error"
message = exchange_record._exchange_status_message("receive_ko")
res = f"Input error: {error}"
else:
message = exchange_record._exchange_status_message("receive_ok")
error = None
error = traceback = None
state = "input_received"
res = message
finally:
exchange_record.write(
{
"edi_exchange_state": state,
"exchange_error": error,
"exchange_error_traceback": traceback,
# FIXME: this should come from _compute_exchanged_on
# but somehow it's failing in send tests (in record tests it works).
"exchanged_on": fields.Datetime.now(),
Expand Down
3 changes: 3 additions & 0 deletions edi_oca/models/edi_exchange_record.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ class EDIExchangeRecord(models.Model):
],
)
exchange_error = fields.Text(string="Exchange error", readonly=True, copy=False)
exchange_error_traceback = fields.Text(
string="Exchange error traceback", readonly=True, copy=False
)
# Relations w/ other records
parent_id = fields.Many2one(
comodel_name="edi.exchange.record",
Expand Down
3 changes: 2 additions & 1 deletion edi_oca/tests/test_backend_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ def test_receive_no_allow_empty_file_record(self):
).exchange_receive(self.record)
# Check the record
msg = "Empty files are not allowed for this exchange type"
self.assertIn(msg, self.record.exchange_error)
self.assertEqual(msg, self.record.exchange_error)
self.assertIn(msg, self.record.exchange_error_traceback)
self.assertEqual(self.record._get_file_content(), "")
self.assertRecordValues(
self.record, [{"edi_exchange_state": "input_receive_error"}]
Expand Down
5 changes: 4 additions & 1 deletion edi_oca/tests/test_backend_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,13 @@ def test_send_record_with_error(self):
[
{
"edi_exchange_state": "output_error_on_send",
"exchange_error": "OOPS! Something went wrong :(",
}
],
)
self.assertIn("OOPS! Something went wrong :(", self.record.exchange_error)
self.assertIn(
"OOPS! Something went wrong :(", self.record.exchange_error_traceback
)

def test_send_invalid_direction(self):
vals = {
Expand Down
5 changes: 4 additions & 1 deletion edi_oca/tests/test_backend_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,13 @@ def test_process_record_with_error(self):
[
{
"edi_exchange_state": "input_processed_error",
"exchange_error": "OOPS! Something went wrong :(",
}
],
)
self.assertIn("OOPS! Something went wrong :(", self.record.exchange_error)
self.assertIn(
"OOPS! Something went wrong :(", self.record.exchange_error_traceback
)

@mute_logger("odoo.models.unlink")
def test_process_no_file_record(self):
Expand Down
6 changes: 4 additions & 2 deletions edi_oca/tests/test_backend_validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,11 @@ def test_receive_validate_record_error(self):
[
{
"edi_exchange_state": "validate_error",
"exchange_error": "Data seems wrong!",
}
],
)
self.assertIn("Data seems wrong!", self.record_in.exchange_error)
self.assertIn("Data seems wrong!", self.record_in.exchange_error_traceback)

def test_generate_validate_record(self):
self.record_out.write({"edi_exchange_state": "new"})
Expand All @@ -87,10 +88,11 @@ def test_generate_validate_record_error(self):
[
{
"edi_exchange_state": "validate_error",
"exchange_error": "Data seems wrong!",
}
],
)
self.assertIn("Data seems wrong!", self.record_out.exchange_error)
self.assertIn("Data seems wrong!", self.record_out.exchange_error_traceback)

def test_validate_record_error_regenerate(self):
self.record_out.write({"edi_exchange_state": "new"})
Expand Down
4 changes: 3 additions & 1 deletion edi_oca/views/edi_exchange_record_views.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
decoration-danger="edi_exchange_state in ['validate_error', 'output_error_on_send', 'output_sent_and_error', 'input_receive_error', 'input_processed_error']"
widget="badge"
/>
<field name="exchange_error" optional="show" />
</tree>
</field>
</record>
Expand Down Expand Up @@ -155,9 +156,10 @@
<page
name="error"
string="Error"
attrs="{'invisible': [('exchange_error', '=', False)]}"
attrs="{'invisible': [('exchange_error_traceback', '=', False)]}"
>
<field name="exchange_error" />
<field name="exchange_error_traceback" />
</page>
<!-- FIXME: this `invisible` domain does not work -->
<page
Expand Down
2 changes: 1 addition & 1 deletion edi_sale_edifact_oca/tests/test_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,4 @@ def test_existing_order(self):
self.exc_record_in.action_exchange_process()
self.assertEqual(self.exc_record_in.edi_exchange_state, "input_processed_error")
err_msg = "Sales order has already been imported before"
self.assertIn(err_msg, self.exc_record_in.exchange_error)
self.assertIn(err_msg, self.exc_record_in.exchange_error_msg)
2 changes: 1 addition & 1 deletion edi_sale_oca/tests/test_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def test_existing_order(self):
self.record.action_exchange_process()
md_onchange.assert_called()
md_btn.assert_called()
self.assertIn(err_msg, self.record.exchange_error)
self.assertIn(err_msg, self.record.exchange_error_msg)

def test_new_order(self):
# Create the order manully and use it via the mock on md_btn
Expand Down
2 changes: 1 addition & 1 deletion edi_storage_oca/components/check.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def _exchange_output_check(self):
self.exchange_record.update(
{
"edi_exchange_state": "output_sent_and_error",
"exchange_error": pycompat.to_text(error_report),
"exchange_error_msg": pycompat.to_text(error_report),
}
)
self.exchange_record._notify_error("process_ko")
Expand Down
4 changes: 2 additions & 2 deletions edi_storage_oca/tests/test_edi_backend_storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ def test_already_sent_process_error(self):
self.record,
{
"edi_exchange_state": "output_sent_and_error",
"exchange_error": "ERROR XYZ: line 2 broken on bla bla",
"exchange_error_msg": "ERROR XYZ: line 2 broken on bla bla",
},
state_paths=("done", "error", "error-report"),
expected_messages=[
Expand Down Expand Up @@ -181,7 +181,7 @@ def test_cron_full_flow(self):
rec2,
{
"edi_exchange_state": "output_sent_and_error",
"exchange_error": "ERROR XYZ: line 2 broken on bla bla",
"exchange_error_msg": "ERROR XYZ: line 2 broken on bla bla",
},
state_paths=("done", "error", "error-report"),
expected_messages=[
Expand Down

0 comments on commit 5ca5d36

Please sign in to comment.