Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[16.0][IMP] edi_oca: Split exchange error and traceback #105

Open
wants to merge 1 commit into
base: 16.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)

Check warning on line 26 in edi_oca/models/edi_backend.py

View check run for this annotation

Codecov / codecov/patch

edi_oca/models/edi_backend.py#L26

Added line #L26 was not covered by tests


def _get_exception_traceback():
buff = StringIO()
traceback.print_exc(file=buff)
traceback_txt = buff.getvalue()
Expand Down Expand Up @@ -228,12 +234,17 @@
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 @@ -300,22 +311,24 @@
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 @@ -325,7 +338,7 @@
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 @@ -337,6 +350,7 @@
{
"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 @@ -495,24 +509,26 @@
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 @@ -543,7 +559,7 @@
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 @@ -552,28 +568,31 @@
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 @@ -87,6 +87,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
8 changes: 6 additions & 2 deletions edi_oca/tests/test_backend_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,12 @@ def test_receive_no_allow_empty_file_record(self):
fake_output="", _edi_receive_break_on_error=False
).exchange_receive(self.record)
# Check the record
msg = "Empty files are not allowed for exchange type"
self.assertIn(msg, self.record.exchange_error)
msg = "Empty files are not allowed for exchange type %(name)s (%(code)s)" % {
"name": self.exchange_type_in.name,
"code": self.exchange_type_in.code,
}
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 @@ -172,9 +173,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
Loading