S2c D6. Seven concrete exceptions over a shared PublicFormApiException
base + a single renderer in bootstrap/app.php produce the contract:
{ "message": "...", "code": "...", "errors"?: {...} }
Codes: SCHEMA_NOT_FOUND (404), TOKEN_EXPIRED (410), TOKEN_REVOKED (410),
SCHEMA_UNPUBLISHED (410), SUBMISSION_ALREADY_SUBMITTED (409),
RATE_LIMITED (429 with Retry-After header), VALIDATION_FAILED (422
with per-field errors).
Used by PublicFormController (resolve) and PublicFormSubmissionController
(load/submit lifecycle). Every public-form endpoint now emits the same
envelope regardless of which branch failed; the renderer only fires on
PublicFormApiException so the authenticated API still uses its default
Laravel shapes.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
24 lines
712 B
PHP
24 lines
712 B
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Exceptions\FormBuilder;
|
|
|
|
/**
|
|
* 422 for per-field validation failures raised by FormValueService when
|
|
* enforcing form_fields.validation_rules. FormRequests still throw
|
|
* Laravel's ValidationException directly; this class is for failures
|
|
* detected below the request layer.
|
|
*/
|
|
final class FieldValidationException extends PublicFormApiException
|
|
{
|
|
/**
|
|
* @param array<string, array<int, string>> $fieldErrors
|
|
*/
|
|
public function __construct(array $fieldErrors, string $message = 'The submitted values failed validation.')
|
|
{
|
|
parent::__construct('VALIDATION_FAILED', 422, $message);
|
|
$this->fieldErrors = $fieldErrors;
|
|
}
|
|
}
|