Handle Validation Errors in UI
After this page, you can map engine validation errors to clear, field-level UI feedback.
Problem
Users see confusing messages when invalid report definitions are submitted.
Prerequisites
- UI form for report builder inputs
- App-layer endpoint/service that returns engine validation errors
Steps
Handle validation results by path and message.
Example error payload returned by your app layer:
json
{
"errors": [
{
"path": "selected_columns.0.field_key",
"message": "Selected field is not exposed by source."
},
{
"path": "sorts.0.field_key",
"message": "Sort field is not sortable."
},
{
"path": "filters.children.1.value",
"message": "Between operators require exactly two values."
}
]
}ts
type DefinitionError = { path: string; message: string };
function mapErrorsByPath(errors: DefinitionError[]) {
return errors.reduce<Record<string, string[]>>((acc, error) => {
if (!acc[error.path]) acc[error.path] = [];
acc[error.path].push(error.message);
return acc;
}, {});
}
async function submitDefinition(payload: unknown) {
const response = await fetch('/app/reports/preview', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
});
const body = await response.json();
if (response.status === 422 && Array.isArray(body.errors)) {
return { ok: false, fieldErrors: mapErrorsByPath(body.errors as DefinitionError[]) };
}
if (!response.ok) {
return { ok: false, globalError: 'Unable to run preview right now.' };
}
return { ok: true, data: body };
}Verify
- Submit a definition with an unknown field and verify field-level error display.
- Submit a definition with invalid
betweenvalue shape and verify correct error message. - Submit a valid definition and verify preview loads with no stale errors.
Common mistakes
- Showing all errors as a single global toast.
- Ignoring the
pathfield and losing precision in UI feedback. - Treating validation failures and infrastructure failures the same way.
- Depending on exact message text for control flow instead of path/category.