Symfony "Type" 约束:"string" 类型的预期参数,"array" 给定异常

Symfony "Type" constraint: Expected argument of type "string", "array" given exception

我有一个表格。例如,它的登录表单:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('phone', TextType::class, [
        'constraints' => [
            new NotBlank(),
            new Type(['type' => 'string']),
            new Length(['max' => 255]),
            new ValueExistsInEntity([
                'entityClass' => User::class,
                'field' => 'phone',
                'message' => 'User not found'
            ])
        ]
    ]);
    $builder->add('password', TextType::class, [
        'constraints' => [
            new NotBlank(),
            new Type(['type' => 'string']),
            new Length(['min' => 8, 'max' => 128])
        ]
    ]);
}

如您所见,它具有 Length 约束。当我将数组发送到表单中的任何字段时,Length 约束会抛出 Symfony\Component\Validator\Exception\UnexpectedTypeException 和 500 状态代码以及消息:

Expected argument of type "string", "array" given

有什么方法可以避免这种情况或将这种异常转化为表单验证错误?

因为 Length 仅是字符串的验证器。对于数组,您必须使用 Count 验证器。

如果您想在同一个验证器中同时使用数组和字符串,您应该实现自己的 Custom validator

我找到的唯一解决方案是创建事件侦听器,它将异常简单地转换为美丽错误(这对我来说没问题,因为我只开发 API,而不是完整堆栈)。

我的异常事件侦听器的简化部分:

namespace AppBundle\EventListener;

use AppBundle\Exceptions\FormValidationException;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\Validator\Exception\ValidatorException;

class ApiExceptionListener
{
    /**
     * @var bool
     */
    public $isKernelDebug;

    public function __construct(bool $isKernelDebug)
    {
        $this->isKernelDebug = $isKernelDebug;
    }

    public function onKernelException(GetResponseForExceptionEvent $event)
    {
        $throwedException = $event->getException();

        $errorBody = [
            'code'    => $throwedException->getCode(),
            'message' => $throwedException->getMessage(),
        ];

        if ($throwedException instanceof ValidatorException) {
            $errorBody['message'] = 'Invalid data has been sent';
        }

        if ($this->isKernelDebug) {
            $errorBody['exception'] = [
                'class'   => get_class($throwedException),
                'message' => $throwedException->getMessage(),
                'code'    => $throwedException->getCode(),
            ];
        }

        $event->setResponse(new JsonResponse(['error' => $errorBody]));
    }
}

服务:

app.event_listener.api_exception:
    class: AppBundle\EventListener\ApiExceptionListener
    arguments: ['%%kernel.debug%%']
    tags:
        - { name: kernel.event_listener, event: kernel.exception, method: onKernelException, priority: 200 }

但我很高兴看到更好的解决方案来处理 Symfony 约束抛出的异常。