Skip to content

Commit bdb9b40

Browse files
authored
Merge pull request #160 from WikiMovimentoBrasil/2025-01-error-visualization
refactor: improve error visualization
2 parents 6176de9 + 65bebc2 commit bdb9b40

File tree

4 files changed

+85
-14
lines changed

4 files changed

+85
-14
lines changed

src/core/models.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,8 @@ class Error(models.TextChoices):
381381
NO_STATEMENTS_VALUE = "no_statements_value", _("No statements with given value")
382382
SITELINK_INVALID = "sitelink_invalid", _("The sitelink id is invalid")
383383
COMBINING_COMMAND_FAILED = "combining_failed", _("The next command failed")
384+
API_USER_ERROR = "api_user_error", _("API returned a User error")
385+
API_SERVER_ERROR = "api_server_error", _("API returned a server error")
384386

385387
error = models.TextField(
386388
null=True,
@@ -406,9 +408,12 @@ def finish(self):
406408
self.save()
407409
self.propagate_status_to_previous_commands()
408410

409-
def error_with_value(self, value: Error):
411+
def error_with_value(self, value: Error, message: str = None):
410412
self.error = value
411-
self.error_with_message(value.label)
413+
if message is not None:
414+
self.error_with_message(message)
415+
else:
416+
self.error_with_message(value.label)
412417

413418
def error_with_exception(self, exception: Exception):
414419
message = getattr(exception, "message", str(exception))
@@ -705,7 +710,9 @@ def run(self, client: Client):
705710
if e.response_message == "Invalid path parameter: 'site_id'":
706711
self.error_with_value(self.Error.SITELINK_INVALID)
707712
else:
708-
self.error_with_exception(e)
713+
self.error_with_value(self.Error.API_USER_ERROR, e.message)
714+
except ServerError as e:
715+
self.error_with_value(self.Error.API_SERVER_ERROR, e.message)
709716
except (ApiException, Exception) as e:
710717
self.error_with_exception(e)
711718

@@ -1033,7 +1040,11 @@ def get_label(self, client: Client, preferred_language="en"):
10331040
if id is None or id == "LAST":
10341041
return None
10351042

1036-
labels = client.get_labels(id)
1043+
try:
1044+
labels = client.get_labels(id)
1045+
except ApiException as e:
1046+
logger.warning(f"[{self}] label call failed: {e.message}")
1047+
return None
10371048

10381049
preferred = labels.get(preferred_language)
10391050

src/core/tests/test_api.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,14 @@ def patch_item_successful(cls, mocker, item_id, json_result):
188188
status_code=200,
189189
)
190190

191+
@classmethod
192+
def patch_item_fail(cls, mocker, item_id, status_code, json_result):
193+
mocker.patch(
194+
cls.wikibase_url(f"/entities/items/{item_id}"),
195+
json=json_result,
196+
status_code=status_code,
197+
)
198+
191199
@classmethod
192200
def add_statement_successful(cls, mocker, item_id):
193201
mocker.patch(

src/core/tests/test_batch_processing.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,3 +399,55 @@ def test_set_sitelink_invalid(self, mocker):
399399
self.assertEqual(commands[0].operation, BatchCommand.Operation.SET_SITELINK)
400400
self.assertEqual(commands[0].status, BatchCommand.STATUS_ERROR)
401401
self.assertEqual(commands[0].error, BatchCommand.Error.SITELINK_INVALID)
402+
403+
@requests_mock.Mocker()
404+
def test_all_errors(self, mocker):
405+
ApiMocker.wikidata_property_data_types(mocker)
406+
ApiMocker.is_autoconfirmed(mocker)
407+
ApiMocker.item_empty(mocker, "Q1234")
408+
ApiMocker.item_empty(mocker, "Q5")
409+
ApiMocker.item_empty(mocker, "Q7")
410+
ApiMocker.property_data_type(mocker, "P5", "quantity")
411+
ApiMocker.sitelink_invalid(mocker, "Q1234", "ptwikix")
412+
ApiMocker.patch_item_fail(mocker, "Q5", 400, {"code": "code", "message": "message"})
413+
ApiMocker.patch_item_fail(mocker, "Q7", 500, {"code": "code", "message": "message"})
414+
ApiMocker.statements(mocker, "Q9", {})
415+
ApiMocker.statements(mocker, "Q11", {
416+
"P5": [{
417+
"id": "Q1234$abcdefgh-uijkl",
418+
"value": {
419+
"type": "value",
420+
"content": {"amount": "+32", "unit": "1"},
421+
},
422+
}],
423+
})
424+
batch = self.parse("""
425+
CREATE_PROPERTY|url
426+
Q1234|P5|12
427+
Q1234|Sptwikix|"Cool article"
428+
Q5|P5|123
429+
Q7|P5|321
430+
-Q9|P5|123
431+
-Q11|P5|123
432+
""")
433+
batch.combine_commands = True
434+
batch.run()
435+
self.assertEqual(batch.status, Batch.STATUS_DONE)
436+
commands = batch.commands()
437+
self.assertEqual(commands[0].operation, BatchCommand.Operation.CREATE_PROPERTY)
438+
self.assertEqual(commands[0].error, BatchCommand.Error.OP_NOT_IMPLEMENTED)
439+
self.assertEqual(commands[1].operation, BatchCommand.Operation.SET_STATEMENT)
440+
self.assertEqual(commands[1].error, BatchCommand.Error.COMBINING_COMMAND_FAILED)
441+
self.assertEqual(commands[2].operation, BatchCommand.Operation.SET_SITELINK)
442+
self.assertEqual(commands[2].error, BatchCommand.Error.SITELINK_INVALID)
443+
self.assertEqual(commands[3].operation, BatchCommand.Operation.SET_STATEMENT)
444+
self.assertEqual(commands[3].error, BatchCommand.Error.API_USER_ERROR)
445+
self.assertEqual(commands[4].operation, BatchCommand.Operation.SET_STATEMENT)
446+
self.assertEqual(commands[4].error, BatchCommand.Error.API_SERVER_ERROR)
447+
self.assertEqual(commands[5].operation, BatchCommand.Operation.REMOVE_STATEMENT_BY_VALUE)
448+
self.assertEqual(commands[5].error, BatchCommand.Error.NO_STATEMENTS_PROPERTY)
449+
self.assertEqual(commands[6].operation, BatchCommand.Operation.REMOVE_STATEMENT_BY_VALUE)
450+
self.assertEqual(commands[6].error, BatchCommand.Error.NO_STATEMENTS_VALUE)
451+
self.assertEqual(len(commands), 7)
452+
for command in commands:
453+
self.assertEqual(command.status, BatchCommand.STATUS_ERROR)

src/web/templates/batch_commands.html

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,25 @@
1111
</span>
1212
</td>
1313

14+
<td >
15+
{% if command.display_label %}
16+
{{ command.display_label }}
17+
{% endif %}
18+
{% if command.entity_url %}<a href="{{ command.entity_url }}">{% endif %}
19+
{{ command.entity_info }}
20+
{% if command.entity_url %}</a>{% endif %}
21+
</td>
22+
1423
{% if command.is_error_status %}
1524

16-
<td colspan="2">
25+
<td>
1726
{{command.message}}
1827
</td>
1928
<td>
2029
{{command.raw}}
2130
</td>
2231

2332
{% else %}
24-
25-
<td >
26-
{% if command.display_label %}
27-
{{ command.display_label }}
28-
{% endif %}
29-
{% if command.entity_url %}<a href="{{ command.entity_url }}">{% endif %}
30-
{{ command.entity_info }}
31-
{% if command.entity_url %}</a>{% endif %}
32-
</td>
3333

3434
<td >
3535
<span class="action action_{{ command.get_action_display.lower }}">

0 commit comments

Comments
 (0)