rich-model-forms-bundle
rich-model-forms-bundle copied to clipboard
better exception mapping when using factories
Right now when using the factory
option together with expected_exception
, all caught exceptions are transformed into form errors that are mapped to the form holding the factory
option.
A simple approach to better map errors to the real cause could be the following: When an exception is caught, check each child form for the expected_exception
option. If one and only one child form declares to handle the caught exception too, map the error to this very form. In all other cases, the behaviour must not change.
Is this is logic followed only at the root form, or in deeper forms as well? In the Park-Manager FormHandler I implemented it like this (root form only):
/**
* Maps a an exception class to a form (by path).
*
* Note: The form-path is about the form, 'profile.username'
* not 'profile.children.username'.
*
* @param string $exceptionClass Fully qualified exception class-name
* @param \Closure $formatter Closure callback to produce one or more FormErrors
*/
$handler->map('ExceptionClass', function (\Throwable $e) {
// 'form-element(property-path)' eg. 'profile.username' or null for root
return [
'form-element(property-path)' => new FormError('Whoops', null, [], null, $e)
];
// Root form
return new FormError('Whoops', null, [], null, $e);
return [null => new FormError('Whoops', null, [], null, $e)];
// Allow multiple FormErrors as an exception might be wrapped
return ['profile.username' => [new FormError('Whoops', null, [], null, $e)]];
});
You take an exception and then map it to a specific Form (using a semi property-path).
The technique of "this" bundle much more powerful 😦 🤷♂️ oh well, less maintenance for me 😸
@sstok Using the term "root form" in the initial description was not quite right. In fact I see it to work for every (compound) form type that uses the factory
option. This can be the root form, but it will work the same with any form type built like that when being used in deeper levels of nested form structures.
Your code example looks very interesting by the way. It seems to me like it basically solves the idea I roughly sketched in #29.