Skip to content

Commit 9137d92

Browse files
committed
Fix error handling / messaging on import validation errors.
Fixes #2705. While we are at it, also improve the usefulness of the error messages.
1 parent 6d65290 commit 9137d92

File tree

2 files changed

+55
-31
lines changed

2 files changed

+55
-31
lines changed

webapp/src/Service/ImportExportService.php

Lines changed: 46 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ public function importContestData(mixed $data, ?string &$errorMessage = null, st
268268
$messages = [];
269269
/** @var ConstraintViolationInterface $error */
270270
foreach ($errors as $error) {
271-
$messages[] = sprintf('%s: %s', $error->getPropertyPath(), $error->getMessage());
271+
$messages[] = sprintf(' • `%s`: %s', $error->getPropertyPath(), $error->getMessage());
272272
}
273273

274274
$errorMessage = sprintf("Contest has errors:\n\n%s", implode("\n", $messages));
@@ -547,7 +547,7 @@ public function getResultsData(
547547
);
548548
continue;
549549
}
550-
550+
551551
if (!$skip && $rank - $skippedTeams <= $contest->getGoldMedals()) {
552552
$awardString = 'Gold Medal';
553553
$lowestMedalPoints = $teamScore->numPoints;
@@ -791,10 +791,13 @@ protected function importGroupData(
791791
$messages = [];
792792
/** @var ConstraintViolationInterface $error */
793793
foreach ($errors as $error) {
794-
$messages[] = sprintf('%s: %s', $error->getPropertyPath(), $error->getMessage());
794+
$messages[] = sprintf(' • `%s`: %s', $error->getPropertyPath(), $error->getMessage());
795795
}
796796

797-
$message .= sprintf("Group at index %d has errors:\n\n%s\n", $index, implode("\n", $messages));
797+
$message .= sprintf("Group at index %d (%s) has errors:\n%s\n\n",
798+
$index,
799+
json_encode($groupItem),
800+
implode("\n", $messages));
798801
$anyErrors = true;
799802
} else {
800803
$allCategories[] = $teamCategory;
@@ -810,7 +813,7 @@ protected function importGroupData(
810813
}
811814

812815
if ($anyErrors) {
813-
return 0;
816+
return -1;
814817
}
815818

816819
foreach ($allCategories as $category) {
@@ -898,10 +901,13 @@ protected function importOrganizationData(
898901
$messages = [];
899902
/** @var ConstraintViolationInterface $error */
900903
foreach ($errors as $error) {
901-
$messages[] = sprintf('%s: %s', $error->getPropertyPath(), $error->getMessage());
904+
$messages[] = sprintf(' • `%s`: %s', $error->getPropertyPath(), $error->getMessage());
902905
}
903906

904-
$message .= sprintf("Organization at index %d has errors:\n\n%s\n", $index, implode("\n", $messages));
907+
$message .= sprintf("Organization at index %d (%s) has errors:\n%s\n\n",
908+
$index,
909+
json_encode($organizationItem),
910+
implode("\n", $messages));
905911
$anyErrors = true;
906912
} else {
907913
$allOrganizations[] = $teamAffiliation;
@@ -917,7 +923,7 @@ protected function importOrganizationData(
917923
}
918924

919925
if ($anyErrors) {
920-
return 0;
926+
return -1;
921927
}
922928

923929
foreach ($allOrganizations as $organization) {
@@ -1146,10 +1152,13 @@ protected function importTeamData(array $teamData, ?string &$message, ?array &$s
11461152
$messages = [];
11471153
/** @var ConstraintViolationInterface $error */
11481154
foreach ($errors as $error) {
1149-
$messages[] = sprintf('%s: %s', $error->getPropertyPath(), $error->getMessage());
1155+
$messages[] = sprintf(' • `%s`: %s', $error->getPropertyPath(), $error->getMessage());
11501156
}
11511157

1152-
$message .= sprintf("Organization for team at index %d has errors:\n\n%s\n", $index, implode("\n", $messages));
1158+
$message .= sprintf("Organization for team at index %d (%s) has errors:\n%s\n\n",
1159+
$index,
1160+
json_encode($teamItem),
1161+
implode("\n", $messages));
11531162
$anyErrors = true;
11541163
} else {
11551164
$createdAffiliations[] = $teamAffiliation;
@@ -1169,10 +1178,13 @@ protected function importTeamData(array $teamData, ?string &$message, ?array &$s
11691178
$messages = [];
11701179
/** @var ConstraintViolationInterface $error */
11711180
foreach ($errors as $error) {
1172-
$messages[] = sprintf('%s: %s', $error->getPropertyPath(), $error->getMessage());
1181+
$messages[] = sprintf(' • `%s`: %s', $error->getPropertyPath(), $error->getMessage());
11731182
}
11741183

1175-
$message .= sprintf("Organization for team at index %d has errors:\n\n%s\n", $index, implode("\n", $messages));
1184+
$message .= sprintf("Organization for team at index %d (%s) has errors:\n%s\n\n",
1185+
$index,
1186+
json_encode($teamItem),
1187+
implode("\n", $messages));
11761188
$anyErrors = true;
11771189
} else {
11781190
$createdAffiliations[] = $teamAffiliation;
@@ -1195,10 +1207,13 @@ protected function importTeamData(array $teamData, ?string &$message, ?array &$s
11951207
$messages = [];
11961208
/** @var ConstraintViolationInterface $error */
11971209
foreach ($errors as $error) {
1198-
$messages[] = sprintf('%s: %s', $error->getPropertyPath(), $error->getMessage());
1210+
$messages[] = sprintf(' • `%s`: %s', $error->getPropertyPath(), $error->getMessage());
11991211
}
12001212

1201-
$message .= sprintf("Group for team at index %d has errors:\n\n%s\n", $index, implode("\n", $messages));
1213+
$message .= sprintf("Group for team at index %d (%s) has errors:\n%s\n\n",
1214+
$index,
1215+
json_encode($teamItem),
1216+
implode("\n", $messages));
12021217
$anyErrors = true;
12031218
} else {
12041219
$createdCategories[] = $teamCategory;
@@ -1244,10 +1259,13 @@ protected function importTeamData(array $teamData, ?string &$message, ?array &$s
12441259
$messages = [];
12451260
/** @var ConstraintViolationInterface $error */
12461261
foreach ($errors as $error) {
1247-
$messages[] = sprintf('%s: %s', $error->getPropertyPath(), $error->getMessage());
1262+
$messages[] = sprintf(' • `%s`: %s', $error->getPropertyPath(), $error->getMessage());
12481263
}
12491264

1250-
$message .= sprintf("Team at index %d has errors:\n\n%s\n", $index, implode("\n", $messages));
1265+
$message .= sprintf("Team at index %d (%s) has errors:\n%s\n\n",
1266+
$index,
1267+
json_encode($teamItem),
1268+
implode("\n", $messages));
12511269
$anyErrors = true;
12521270
} else {
12531271
$allTeams[] = $team;
@@ -1265,7 +1283,7 @@ protected function importTeamData(array $teamData, ?string &$message, ?array &$s
12651283
}
12661284

12671285
if ($anyErrors) {
1268-
return 0;
1286+
return -1;
12691287
}
12701288

12711289
foreach ($createdAffiliations as $affiliation) {
@@ -1348,10 +1366,13 @@ protected function importAccountData(
13481366
$messages = [];
13491367
/** @var ConstraintViolationInterface $error */
13501368
foreach ($errors as $error) {
1351-
$messages[] = sprintf('%s: %s', $error->getPropertyPath(), $error->getMessage());
1369+
$messages[] = sprintf(' • `%s`: %s', $error->getPropertyPath(), $error->getMessage());
13521370
}
13531371

1354-
$message .= sprintf("Team for user at index %d has errors:\n\n%s\n", $index, implode("\n", $messages));
1372+
$message .= sprintf("Team for user at index %d (%s) has errors:\n%s\n\n",
1373+
$index,
1374+
json_encode($accountItem),
1375+
implode("\n", $messages));
13551376
$anyErrors = true;
13561377
} else {
13571378
$newTeams[] = [
@@ -1397,10 +1418,13 @@ protected function importAccountData(
13971418
$messages = [];
13981419
/** @var ConstraintViolationInterface $error */
13991420
foreach ($errors as $error) {
1400-
$messages[] = sprintf('%s: %s', $error->getPropertyPath(), $error->getMessage());
1421+
$messages[] = sprintf(' • `%s`: %s', $error->getPropertyPath(), $error->getMessage());
14011422
}
14021423

1403-
$message .= sprintf("User at index %d has errors:\n\n%s\n", $index, implode("\n", $messages));
1424+
$message .= sprintf("User at index %d (%s) has errors:\n%s\n\n",
1425+
$index,
1426+
json_encode($accountItem),
1427+
implode("\n", $messages));
14041428
$anyErrors = true;
14051429
} else {
14061430
$allUsers[] = $user;
@@ -1412,7 +1436,7 @@ protected function importAccountData(
14121436
}
14131437

14141438
if ($anyErrors) {
1415-
return 0;
1439+
return -1;
14161440
}
14171441

14181442
foreach ($allUsers as $user) {

webapp/tests/Unit/Service/ImportExportServiceTest.php

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ public function provideImportContestDataErrors(): Generator
105105
'start-time' => '2020-01-01T12:34:56+02:00',
106106
'scoreboard-freeze-length' => '30:00',
107107
],
108-
"Contest has errors:\n\nname: This value should not be blank.\nshortname: This value should not be blank."
108+
"Contest has errors:\n\n • `name`: This value should not be blank.\n • `shortname`: This value should not be blank."
109109
];
110110
}
111111

@@ -501,7 +501,7 @@ public function testImportAccountsJsonError(): void
501501
// Remove the file, we don't need it anymore.
502502
unlink($fileName);
503503

504-
self::assertEquals(0, $importCount);
504+
self::assertEquals(-1, $importCount);
505505
self::assertMatchesRegularExpression('/Only alphanumeric characters and _-@. are allowed/', $message);
506506

507507
$postCount = $em->getRepository(User::class)->count([]);
@@ -870,8 +870,8 @@ public function testImportTeamsJsonError(): void
870870
// Remove the file, we don't need it anymore.
871871
unlink($fileName);
872872

873-
self::assertMatchesRegularExpression('/name: This value should not be blank./', $message);
874-
self::assertEquals(0, $importCount);
873+
self::assertMatchesRegularExpression('/.*`name`: This value should not be blank.*/', $message);
874+
self::assertEquals(-1, $importCount);
875875

876876
$postCount = $em->getRepository(Team::class)->count([]);
877877
self::assertEquals($preCount, $postCount);
@@ -908,8 +908,8 @@ public function testImportTeamsJsonErrorEmptyString(): void
908908
// Remove the file, we don't need it anymore.
909909
unlink($fileName);
910910

911-
self::assertMatchesRegularExpression('/name: This value should not be blank./', $message);
912-
self::assertEquals(0, $importCount);
911+
self::assertMatchesRegularExpression('/.*`name`: This value should not be blank.*/', $message);
912+
self::assertEquals(-1, $importCount);
913913

914914
$postCount = $em->getRepository(Team::class)->count([]);
915915
self::assertEquals($preCount, $postCount);
@@ -1050,8 +1050,8 @@ public function testImportGroupsJsonError(): void
10501050
// Remove the file, we don't need it anymore.
10511051
unlink($fileName);
10521052

1053-
self::assertMatchesRegularExpression('/name: This value should not be blank/', $message);
1054-
self::assertEquals(0, $importCount);
1053+
self::assertMatchesRegularExpression('/.*`name`: This value should not be blank.*/', $message);
1054+
self::assertEquals(-1, $importCount);
10551055

10561056
$postCount = $em->getRepository(TeamCategory::class)->count([]);
10571057
self::assertEquals($preCount, $postCount);
@@ -1150,7 +1150,7 @@ public function testImportOrganizationsErrorJson(): void
11501150
unlink($fileName);
11511151

11521152
self::assertMatchesRegularExpression('/ISO3166-1 alpha-3 values are allowed/', $message);
1153-
self::assertEquals(0, $importCount);
1153+
self::assertEquals(-1, $importCount);
11541154

11551155
$postCount = $em->getRepository(TeamAffiliation::class)->count([]);
11561156
self::assertEquals($preCount, $postCount);

0 commit comments

Comments
 (0)