Symfony - Нет расширения, способного загрузить конфигурацию (подписчик / прослушивание событий) (обработка исключений REST API с выводом JSON)

Цель

Здравствуйте, я новичок в Symfony и пытаюсь создать функциональность обработки исключений / ошибок для нашего веб-API.

Требования

Когда пользователь делает недопустимый запрос к нашему API, мы хотим вернуть простой объект JSON, который выглядит примерно так:

{"errorCode": 1234567, "errorMessage": "Parameter 1 is invalid. String expected"}

В дополнение к специфичным для API ошибкам мы также хотим подключиться к встроенной обработке исключений в Symfony и использовать ее повторно, но вместо того, чтобы возвращать страницу с ошибкой HTML (что происходит по умолчанию), мы хотим вернуть объект JSON, такой как:

{"errorCode": 404, "errorMessage": "Not found"}

Текущий подход

Очевидно, что мы хотим, чтобы это было реализовано наиболее эффективным образом, поэтому, проведя некоторое исследование, я обнаружил, что я считаю отличным подходом, который затем я могу адаптировать к нашим конкретным потребностям. Вот учебник, которому я следовал:

https://knpuniversity.com/screencast/symfony-rest2

В итоге я купил этот курс, чтобы получить доступ к полному коду. Проблема в том, что он был написан для Symfony 2, но мы работаем с Symfony 3.3, поэтому некоторые вещи устарели, и я пока не смог запустить пример.

Код

Итак, я разместил некоторые соответствующие коды ниже. (Я, очевидно, не могу опубликовать весь код, но разместил, как мы надеемся, соответствующие части общедоступного кода).

services.yml (их версия, Symfony 2 Style)

api_exception_subscriber:
        class: AppBundle\EventListener\ApiExceptionSubscriber
        arguments: []
        tags:
            - { name: kernel.event_subscriber }

services.yml (мой полный файл со всеми удаленными комментариями) Это включает в себя измененную версию того, что у них есть выше (надеюсь, это правильный способ работы Symfony 3.3). ПРИМЕЧАНИЕ. Все, что было частью личного кода, который я не могу показать, я заменил словом " что-то ".

parameters:

services:
    _defaults:
        autowire: true
        autoconfigure: true
        public: false

    AppBundle\:
        resource: '../../src/AppBundle/*'
        exclude: '../../src/AppBundle/{Entity,Repository,Tests}'

    AppBundle\Controller\:
        resource: '../../src/AppBundle/Controller'
        public: true
        tags: ['controller.service_arguments']

    AppBundle\EventListener\ApiExceptionSubscriber:
        arguments:
        - ['%something.something%']
        tags:
        - {name: 'kernel.event_subscriber'}

routing.yml (соответствующий раздел их файла)

app_api:
    resource: "@AppBundle/Controller/Api"
    type:     annotation
    defaults:
        _format: json

routing.yml (мой полный файл) - ПРИМЕЧАНИЕ. Мне пришлось добавить здесь "_format: json" непосредственно в раздел "app", а не "app_api", потому что в нашем REST API все наши URL находятся на корневом уровне, и не должны иметь префикс "api", например http://localhost/api/someMethod/someMethodParameter как в коде учебника

app:
    resource: '@AppBundle/Controller/'
    type: annotation
    defaults: {_format:json}
yml_route:
  path: /yml-route
  defaults:
    _controller: AppBundle:Default:yml
awesome_route:
  path: /awesome-route/{ic}
  defaults:
    _controller: AppBundle:Rest:awesomeRoute

src / AppBundle / RestController.php (отредактировано, чтобы показать только базовую структуру)

    <?php 
    namespace AppBundle\Controller;
    use FOS\RestBundle\Controller\Annotations as Rest;
    use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
    use Symfony\Bundle\FrameworkBundle\Controller\Controller;
    use Symfony\Component\HttpFoundation\JsonResponse;
    use Symfony\Component\HttpFoundation\Response;
    use Symfony\Component\Serializer\Serializer;
    use Symfony\Component\Serializer\Encoder\XmlEncoder;
    use Symfony\Component\Serializer\Encoder\JsonEncoder;
    use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer;
    use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
    use Symfony\Component\HttpFoundation\Request;

    class RestController extends Controller {

       public function doSomething($id)
       {
          // Code to populate $result with data from database is here
          return new JsonResponse($result);
       }

    // This file contains many different functions similar to doSomething() which retrieve the request for the API caller.
   // For example, doSomething() can be accessed via http://localhost/app_dev.php/doSomething/123
    }

src / AppBundle / Api / ApiProblem.php (отредактировано, чтобы показать только базовую структуру)

namespace AppBundle\Api;
use Symfony\Component\HttpFoundation\Response;

class ApiProblem
{
   // Code relevant to this class is in here
}

src / AppBundle / Api / ApiProblemException.php (отредактировано, чтобы показать только базовую структуру)

    <?php

    namespace AppBundle\Api;
    use Symfony\Component\HttpKernel\Exception\HttpException;

    class ApiProblemException extends HttpException
    {
       private $apiProblem;

       public function __construct($severalParametersWhichICannotListHereBecauseCodeIsPrivate) {
       // Does some stuff and then calls the parent:__construct
       // Includes a getter for $apiProblem
    }
}

src / AppBundle / EventListener / ApiExceptionSubscriber.php (отредактировано, чтобы показать только базовую структуру)

<?php 
namespace AppBundle\EventListener;
use AppBundle\Api\ApiProblem;
use AppBundle\Api\ApiProblemException;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpKernel\KernelEvents;

class ApiExceptionSubscriber implements EventSubscriberInterface
{
   // Code relevant to this subscriber is here
}

Проблема

Я получаю следующую ошибку при попытке запустить любой тип команды из командной строки bin / console:

    C:\htdocs\projects\myproject>php bin/console debug:container
    PHP Fatal error:  Uncaught Symfony\Component\DependencyInjection\Exception\InvalidArgumentException: T
    here is no extension able to load the configuration for "AppBundle\EventListener\ApiExceptionSubscribe
    r" (in C:\htdocs\projects\myproject\app/config\services.yml). Looked for namespace "AppBundle\EventListe
    ner\ApiExceptionSubscriber", found "framework", "security", "twig", "monolog", "swiftmailer", "doctrin
    e", "sensio_framework_extra", "demontpx_parsedown", "doctrine_cache", "doctrine_migrations", "debug",
    "web_profiler", "sensio_distribution", "web_server" in C:\htdocs\projects\myproject\vendor\symfony\symfo
    ny\src\Symfony\Component\DependencyInjection\Loader\YamlFileLoader.php:644
    Stack trace:
    #0 C:\htdocs\projects\myproject\vendor\symfony\symfony\src\Symfony\Component\DependencyInjection\Loader\
    YamlFileLoader.php(614): Symfony\Component\DependencyInjection\Loader\YamlFileLoader->validate(Array,
    'C:\\htdocs\\proje...')
    #1 C:\htdocs\projects\myproject\vendor\symfony\symfony\src\Symfony\Component\DependencyInjection\Loader\
    YamlFileLoad in C:\htdocs\projects\myproject\vendor\symfony\symfony\src\Symfony\Component\Config\Loader\
    FileLoader.php on line 179

    Fatal error: Uncaught Symfony\Component\DependencyInjection\Exception\InvalidArgumentException: There
    is no extension able to load the configuration for "AppBundle\EventListener\ApiExceptionSubscriber" (i
    n C:\htdocs\projects\myproject\app/config\services.yml). Looked for namespace "AppBundle\EventListener\A
    piExceptionSubscriber", found "framework", "security", "twig", "monolog", "swiftmailer", "doctrine", "
    sensio_framework_extra", "demontpx_parsedown", "doctrine_cache", "doctrine_migrations", "debug", "web_
    profiler", "sensio_distribution", "web_server" in C:\htdocs\projects\myproject\vendor\symfony\symfony\sr
    c\Symfony\Component\Config\Loader\FileLoader.php on line 179

    Symfony\Component\Config\Exception\FileLoaderLoadException: There is no extension able to load the con
    figuration for "AppBundle\EventListener\ApiExceptionSubscriber" (in C:\htdoc
    fig\services.yml). Looked for namespace "AppBundle\EventListener\ApiExceptio
    work", "security", "twig", "monolog", "swiftmailer", "doctrine", "sensio_fra
    arsedown", "doctrine_cache", "doctrine_migrations", "debug", "web_profiler",
    eb_server" in C:\htdocs\projects\myproject\app/config\services.yml (which is b
    ocs\projects\myproject\app/config\config.yml"). in C:\htdocs\projects\myproject\
    \Symfony\Component\Config\Loader\FileLoader.php on line 179

    Call Stack:
        1.4353    6149416   1. Symfony\Component\Debug\ErrorHandler->handleExcep
    myproject\vendor\symfony\symfony\src\Symfony\Component\Debug\ErrorHandler.php:

Что я пробовал

Я отлаживал это в течение последних нескольких дней и прочитал много связанных обсуждений по переполнению стека. Я довольно новичок в службах, подписчиках и внедрении зависимостей, и я неоднократно пытался редактировать и маршруты., И сервисы. Я также получал некоторые исключения из циклических ссылок, но думаю, что исправил их сейчас. Я надеялся, что кто-нибудь может дать мне какое-то руководство и, надеюсь, помочь мне превратить это в рабочий пример Symfony 3.3, из которого я могу извлечь уроки. Если вам нужна дополнительная информация, пожалуйста, дайте мне знать.

Из того, что я узнал, автоматическое подключение / автоконфигурирование сервисов в Symfony 3.3 кажется новым, и я думаю, что это может повлиять, но я не уверен. Я попытался отключить обе эти настройки в services.yml, но безуспешно.

0 ответов

Другие вопросы по тегам