Skip to content

Commit 79d6ccc

Browse files
committed
improve error merging
1 parent 95bc2ee commit 79d6ccc

File tree

3 files changed

+87
-6
lines changed

3 files changed

+87
-6
lines changed

packages/outbox/index.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
import outbox, { Outbox, getOutbox } from "./src/outbox.js";
1+
import outbox, { Outbox, getOutbox, mergeErrors } from "./src/outbox.js";
22
export default outbox;
3-
export { Outbox, getOutbox };
3+
export { Outbox, getOutbox, mergeErrors };
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import { mergeErrors } from "../outbox.js";
2+
3+
test("merge errors - simple", () => {
4+
const error1 = { test: "invalid data" },
5+
error2 = { test: "required", test2: "required" },
6+
merged1 = { test: "invalid data • required", test2: "required" },
7+
merged2 = { test: "required • invalid data", test2: "required" };
8+
expect(mergeErrors(error1, error2)).toStrictEqual(merged1);
9+
expect(mergeErrors(error2, error1)).toStrictEqual(merged2);
10+
});
11+
12+
test("merge errors - array", () => {
13+
const error1 = { test: [null, { value: "invalid data" }] },
14+
error2 = { test: [{ value: "required" }, { value: "required" }] },
15+
merged1 = {
16+
test: [{ value: "required" }, { value: "invalid data • required" }],
17+
},
18+
merged2 = {
19+
test: [{ value: "required" }, { value: "required • invalid data" }],
20+
};
21+
expect(mergeErrors(error1, error2)).toStrictEqual(merged1);
22+
expect(mergeErrors(error2, error1)).toStrictEqual(merged2);
23+
});
24+
25+
test("merge errors - mixed types", () => {
26+
const error1 = { test: [null, { value: "invalid data" }] },
27+
error2 = { test: "error" };
28+
expect(mergeErrors(error1, error2)).toStrictEqual(error2);
29+
expect(mergeErrors(error2, error1)).toStrictEqual(error1);
30+
});
31+
32+
test("merge errors - nested array", () => {
33+
const error1 = {
34+
test: [null, { items: [null, { value: "invalid data" }] }],
35+
},
36+
error2 = {
37+
test: [
38+
null,
39+
{ items: [{ value: "required" }, { value: "required" }] },
40+
],
41+
},
42+
merged1 = {
43+
test: [
44+
{},
45+
{
46+
items: [
47+
{ value: "required" },
48+
{ value: "invalid data • required" },
49+
],
50+
},
51+
],
52+
},
53+
merged2 = {
54+
test: [
55+
{},
56+
{
57+
items: [
58+
{ value: "required" },
59+
{ value: "required • invalid data" },
60+
],
61+
},
62+
],
63+
};
64+
expect(mergeErrors(error1, error2)).toStrictEqual(merged1);
65+
expect(mergeErrors(error2, error1)).toStrictEqual(merged2);
66+
});
67+
68+
test("merge errors - diff array length", () => {
69+
const error1 = { test: [null, { value: "invalid data" }] },
70+
error2 = { test: [{ value: "required" }] },
71+
merged = {
72+
test: [{ value: "required" }, { value: "invalid data" }],
73+
};
74+
expect(mergeErrors(error1, error2)).toStrictEqual(merged);
75+
expect(mergeErrors(error2, error1)).toStrictEqual(merged);
76+
});

packages/outbox/src/outbox.js

+9-4
Original file line numberDiff line numberDiff line change
@@ -336,15 +336,19 @@ class Outbox {
336336

337337
// Validate a record before adding it to the outbox
338338
validate(data, modelConf) {
339-
const errors = {};
339+
let errors = {};
340340
this.app
341341
.callPlugins("validate", [data, modelConf])
342342
.forEach((pluginErrors) => {
343-
mergeErrors(errors, pluginErrors);
343+
errors = this.mergeErrors(errors, pluginErrors);
344344
});
345345
return errors;
346346
}
347347

348+
mergeErrors(errors, nextErrors) {
349+
return mergeErrors(errors, nextErrors);
350+
}
351+
348352
// Send a single item from the outbox to the server
349353
sendItem() {
350354
throw new Error(
@@ -1128,14 +1132,15 @@ class Outbox {
11281132
}
11291133
}
11301134

1131-
function mergeErrors(errors, newErrors) {
1135+
export function mergeErrors(errors, newErrors) {
11321136
if (
11331137
!newErrors ||
11341138
typeof newErrors !== "object" ||
11351139
!Object.keys(newErrors).length
11361140
) {
11371141
return errors;
11381142
}
1143+
errors = { ...errors };
11391144
Object.entries(newErrors).forEach(([key, newError]) => {
11401145
const error = errors[key];
11411146
if (
@@ -1148,7 +1153,7 @@ function mergeErrors(errors, newErrors) {
11481153
errors[key] = error + " • " + newError;
11491154
} else if (Array.isArray(error)) {
11501155
errors[key] = error
1151-
.map((err, i) => mergeErrors(err, newError[i]))
1156+
.map((err, i) => mergeErrors(err || {}, newError[i]))
11521157
.concat(newError.slice(error.length));
11531158
} else if (typeof error === "object") {
11541159
errors[key] = mergeErrors(error, newError);

0 commit comments

Comments
 (0)