Api 平台自定义异常及翻译消息

Vis*_*nna 1 api validation symfony api-platform.com

我在 api 平台中使用带有自定义控制器的自定义端点作为用户实例。

class PayingMembershipForOthersController
{

    private ValidatorInterface $validator;

    public function __construct(ValidatorInterface $validator)
    {
        $this->validator = $validator;
    }

    public function __invoke(User $data)
    {
        $this->validator->validate($data);
        try {
           $paymentService->paymentMembership($data);
        } catch(\Exception $e) {
           throw $e
        }
        return $data;
    }

}
Run Code Online (Sandbox Code Playgroud)

如果找不到用户,我的 $userService 会抛出自定义异常,如下所示。

class XXXException extends \Exception
{
    public function __construct(
        $message = "user.notfound.message",  // Translation file key.
        $code = 0,
        Throwable $previous = null
    ) {
        parent::__construct($message, $code, $previous);
    }
}
Run Code Online (Sandbox Code Playgroud)

所以在这里我想发送翻译消息( UserNotFound [de_DE] 和 UserNotFound [en_EN]。所以你可以在这里帮助我吗?

提前致谢..!!!

小智 7

API 平台有两个有用的工具可以处理Exception:

  1. HTTP 状态异常,
  2. 异常事件订阅者。

第一个允许您从代码的任何位置引发异常。API 平台会捕获它,然后将其转换为漂亮的Response:

# config/packages/api_platform.yaml

api_platform:
    # ...
    exception_to_status:
        App\Exception\MyException: 400
        App\Exception\AnotherException: 500
Run Code Online (Sandbox Code Playgroud)

下一个允许捕获抛出的异常并处理它。在您的情况下,有效负载是将异常消息翻译为适当的语言。在此示例中,我使用Symfony 翻译服务:


namespace App\EventSubscriber;


use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Contracts\Translation\TranslatorInterface;

class ExceptionSubscriber implements EventSubscriberInterface
{
    private TranslatorInterface $translator;

    public function __construct(TranslatorInterface $translator)
    {
        $this->translator = $translator;
    }

    public static function getSubscribedEvents()
    {
        return [
           KernelEvents::EXCEPTION => ['translateException'],
        ];
    }

    public function translateException(ExceptionEvent $event): void
    {
        $currentException = $event->getThrowable();
        $currentMessage = $currentException->getMessage();

        $translatedMessage = $this->translator->trans($currentMessage);
        $exceptionClass = get_class($currentException);
        $translatedException = new $exceptionClass($translatedMessage);

        $event->setThrowable($translatedException);
    }
}
Run Code Online (Sandbox Code Playgroud)

这样,每个未捕获的异常都将被转换,然后转换为 HTTP 错误响应。