Skip to content

Commit e3b2d37

Browse files
committed
form is now available as an argument in onError
1 parent 447473b commit e3b2d37

File tree

4 files changed

+57
-53
lines changed

4 files changed

+57
-53
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1010
### Added
1111

1212
- Exported `ClientValidationAdapter` from `sveltekit-supoerforms/adapters`.
13+
- `form` is now available as an argument in [onError](https://superforms.rocks/concepts/events#onerror), so it can be modified as in `onUpdate`.
1314

1415
### Fixed
1516

src/lib/client/superForm.ts

Lines changed: 41 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ export type FormOptions<
144144
onError:
145145
| 'apply'
146146
| ((event: {
147+
form: SuperValidated<T, M, In>;
147148
result: {
148149
type: 'error';
149150
status?: number;
@@ -965,6 +966,34 @@ export function superForm<
965966
);
966967
}
967968

969+
function Form_capture(removeFilesfromData = true): SuperFormSnapshot<T, M, In> {
970+
let data = Data.form;
971+
let tainted = Data.tainted;
972+
973+
if (removeFilesfromData) {
974+
const removed = removeFiles(Data.form);
975+
data = removed.data;
976+
const paths = removed.paths;
977+
978+
if (paths.length) {
979+
tainted = clone(tainted) ?? {};
980+
setPaths(tainted, paths, false);
981+
}
982+
}
983+
984+
return {
985+
valid: Data.valid,
986+
posted: Data.posted,
987+
errors: Data.errors,
988+
data,
989+
constraints: Data.constraints,
990+
message: Data.message,
991+
id: Data.formId,
992+
tainted,
993+
shape: Data.shape
994+
};
995+
}
996+
968997
async function Form_updateFromValidation(form: SuperValidated<T, M, In>, successResult: boolean) {
969998
if (form.valid && successResult && Form_shouldReset(form.valid, successResult)) {
970999
Form_reset({ message: form.message, posted: true });
@@ -1466,9 +1495,6 @@ export function superForm<
14661495
if (options.applyAction && pageUpdate.form && typeof pageUpdate.form === 'object') {
14671496
const actionData = pageUpdate.form;
14681497

1469-
// Check if it is an error result, sent here from formEnhance
1470-
if (actionData.type == 'error') return;
1471-
14721498
for (const newForm of Context_findValidationForms(actionData)) {
14731499
const isInitial = initialForms.has(newForm);
14741500

@@ -1675,11 +1701,15 @@ export function superForm<
16751701
async function triggerOnError(
16761702
// eslint-disable-next-line @typescript-eslint/no-explicit-any
16771703
result: { type: 'error'; status?: number; error: any },
1678-
thrown: boolean
1704+
status: number
16791705
) {
1706+
const form: SuperValidated<T, M, In> = Form_capture(false);
1707+
1708+
result.status = status;
1709+
16801710
// Check if the error message should be replaced
16811711
if (options.onError !== 'apply') {
1682-
const event = { result, message: Message };
1712+
const event = { result, message: Message, form };
16831713

16841714
for (const onErrorEvent of formEvents.onError) {
16851715
if (
@@ -1698,24 +1728,18 @@ export function superForm<
16981728
});
16991729
}
17001730

1701-
// Set error http status, unless already set
1702-
if (!result.status || result.status < 400) {
1703-
result.status = thrown ? 500 : 400;
1704-
}
1705-
17061731
if (options.applyAction) {
17071732
if (options.onError == 'apply') {
17081733
await applyAction(result);
17091734
} else {
17101735
// Transform to failure, to avoid data loss
17111736
// Set the data to the error result, so it will be
17121737
// picked up in page.subscribe in superForm.
1713-
const failResult = {
1738+
await applyAction({
17141739
type: 'failure',
17151740
status: Form_resultStatus(result.status),
1716-
data: result
1717-
} as const;
1718-
await applyAction(failResult);
1741+
data: { form }
1742+
});
17191743
}
17201744
}
17211745
}
@@ -1748,7 +1772,7 @@ export function superForm<
17481772
await event(submit);
17491773
} catch (error) {
17501774
cancel();
1751-
triggerOnError({ type: 'error', error, status: Form_resultStatus(500) }, true);
1775+
triggerOnError({ type: 'error', error }, 500);
17521776
}
17531777
}
17541778
}
@@ -1983,7 +2007,7 @@ export function superForm<
19832007
await Form_updateFromActionResult(result);
19842008
}
19852009
} else {
1986-
await triggerOnError(result, false);
2010+
await triggerOnError(result, Math.max(result.status ?? 500, 500));
19872011
}
19882012
}
19892013
}
@@ -2091,26 +2115,7 @@ export function superForm<
20912115

20922116
options: options as T extends T ? FormOptions<T, M> : never,
20932117

2094-
capture() {
2095-
const { data, paths } = removeFiles(Data.form);
2096-
let tainted = Data.tainted;
2097-
if (paths.length) {
2098-
tainted = clone(tainted) ?? {};
2099-
setPaths(tainted, paths, false);
2100-
}
2101-
2102-
return {
2103-
valid: Data.valid,
2104-
posted: Data.posted,
2105-
errors: Data.errors,
2106-
data,
2107-
constraints: Data.constraints,
2108-
message: Data.message,
2109-
id: Data.formId,
2110-
tainted,
2111-
shape: Data.shape
2112-
};
2113-
},
2118+
capture: Form_capture,
21142119

21152120
restore: ((snapshot: SuperFormSnapshot<T, M>) => {
21162121
rebind({ form: snapshot, untaint: snapshot.tainted ?? true });

src/routes/(v2)/v2/Navigation.svelte

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@
6767
'spa-error',
6868
'issue-470',
6969
'issue-484',
70-
'component-regen'
70+
'component-regen',
71+
'issue-485'
7172
].sort();
7273
</script>
7374

src/routes/(v2)/v2/issue-485/+page.svelte

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,21 @@
77
import { debounce } from 'throttle-debounce';
88
99
const { form, errors, message, enhance, submit, submitting } = superForm(
10-
defaults({ email: '[email protected]' }, zod(schema)),
10+
defaults({ email: '[email protected]', name: 'aaa' }, zod(schema)),
1111
{
12-
onError(event) {
12+
onError({ result, form }) {
1313
console.log('=== onError ===');
1414
15-
/*
16-
1. It's not possible to use the SuperValidated data from onError,
17-
as it can be caught in onSubmit where it doesn't exist.
18-
19-
You need to update the stores directly.
20-
*/
21-
$message = JSON.stringify(event, null, 2);
15+
form.message = JSON.stringify(result.error, null, 2);
2216
2317
// Cast the error, as its type isn't unknown.
24-
const error = event.result.error as Record<string, unknown>;
18+
const error = result.error as unknown as {
19+
status: number;
20+
errors: Record<string, string[]>;
21+
} & Record<string, unknown>;
2522
26-
$errors = error.errors as Record<string, string[]>;
23+
result.status = error.status;
24+
form.errors = error.errors;
2725
},
2826
async onUpdate({ form, result }) {
2927
console.log('=== onUpdate ===');
@@ -33,7 +31,7 @@
3331
return;
3432
}
3533
36-
const isSuccess = Math.random() >= 0.5;
34+
const isSuccess = false; //Math.random() >= 0.5;
3735
console.log('isSuccess', isSuccess);
3836
3937
if (isSuccess) {
@@ -56,12 +54,11 @@
5654
}
5755
};
5856
59-
const shouldThrow = Math.random() >= 0.5;
57+
const shouldThrow = false; //Math.random() >= 0.5;
6058
console.log('shouldThrow', shouldThrow);
6159
6260
if (shouldThrow) {
6361
// 3. This will update the status in the next release:
64-
result.status = 422;
6562
throw madeupProblemDetails;
6663
}
6764
@@ -75,7 +72,7 @@
7572
},
7673
SPA: true,
7774
validators: zod(schema),
78-
resetForm: true
75+
resetForm: false
7976
}
8077
);
8178
@@ -84,7 +81,7 @@
8481

8582
<SuperDebug data={$form} />
8683

87-
<h3>Superforms testing ground - Zod</h3>
84+
<h3>onError testing</h3>
8885

8986
{#if $message}
9087
<pre

0 commit comments

Comments
 (0)