EasyCorp / EasyAdminBundle

EasyAdmin is a fast, beautiful and modern admin generator for Symfony applications.
MIT License
4.09k stars 1.03k forks source link

EntityRemoveException should leverage the `previous: $exception` constructor parameters #6615

Open allan-simon opened 16 hours ago

allan-simon commented 16 hours ago

Short description of what this feature will allow to do:

It will allow to have a more precise context of the original exception

Currently for EntityRemoveException (and certainly other exception in easyadmin bundle) the usage is the following

        } catch (ForeignKeyConstraintViolationException $e) {

            throw new EntityRemoveException(['entity_name' => $context->getEntity()->getName(), 'message' => $e->getMessage()]);

        }

i.e

        } catch (CodeException $e) {
            throw new BusinessException([]);
        }

This allow to have the original CodeException message but not it's stacktrace , so information are loose

instead, PHP already have a builtin mechanism for that , which is the previous: Exception $e parameter in Exception constructors which allow to do the following construction (adminting you don't override the constructor


        } catch (CodeException $e) {
            throw new BusinessException('my business message',  previous: $e );
        }

This allow to

  1. keep both the business and code stacktrace
  2. allow you to not have to reconstruct a "original message : %s"

(One short paragraph is enough)

Example of how to use this feature (Show some PHP code and/or YAML config explaining how to use this feature in a real app)

transform

final class EntityRemoveException extends BaseException
{
    public function __construct(array $parameters = [])
    {
        $exceptionContext = new ExceptionContext(
            'exception.entity_remove',
            sprintf('There is a ForeignKeyConstraintViolationException for the Doctrine entity associated with "%s". Solution: disable the "delete" action for this CRUD controller or configure the "cascade={"remove"}" attribute for the related field in the Doctrine entity. Full exception: %s', $parameters['entity_name'], $parameters['message']),
            $parameters,
            409
        );

        parent::__construct($exceptionContext);
    }
}

into

final class EntityRemoveException extends BaseException
{
    public function __construct(string $entityName, Exception $previous)
    {
        $exceptionContext = new ExceptionContext(
            'exception.entity_remove',
            sprintf('There is a ForeignKeyConstraintViolationException for the Doctrine entity associated with "%s". Solution: disable the "delete" action for this CRUD controller or configure the "cascade={"remove"}" attribute for the related field in the Doctrine entity.', $parameters['entity_name']),
            $parameters,
            409
        );

        parent::__construct($exceptionContext, previous $previous);
    }
}

so that you could then do

        } catch (ForeignKeyConstraintViolationException $e) {

            throw new EntityRemoveException($context->getEntity()->getName(),  previous: $e);

        }
allan-simon commented 16 hours ago

if you want I can propose a PR