1

After installing "RESTful Web Services" module, if I execute this API request:

curl --request GET \
  --url 'http://localhost/resourceNotFound?_format=json'

I got following error (which is expected):

{
    "message": "No route found for \"GET http:\/\/localhost\/resourceNotFound\""
}

Let's say I would like to change that error to:

{
  "code": 60,
  "message": "Resource not found",
  "description": "The requested URI or the requested resource does not exist."
}

How to do that?

5
  • These type of messages are comming from web/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php Commented Jan 12 at 22:17
  • 1
    No they are not. core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php is test code.
    – mona lisa
    Commented Jan 12 at 22:23
  • @cilefen you are right. It's coming from vendor/symfony/http-kernel/EventListener/RouterListener.php. So the question is how to override Symfony class/method I guess! Commented Jan 12 at 22:58
  • 1
    core/modules/workspaces/src/EventSubscriber/WorkspaceRequestSubscriber.php is an example of overriding that listener.
    – mona lisa
    Commented Jan 13 at 0:45
  • Would you post how the module starts: structure, namespace, use clauses, ... I'll try to complete it as much as I can Commented Jan 13 at 14:08

1 Answer 1

3

You don't want to override the exception messages when they are thrown in routing or elsewhere. Better use an exception handler to catch all JSON 404 exceptions:

/src/EventSubscriber/MymoduleExceptionSubscriber.php

<?php

namespace Drupal\mymodule\EventSubscriber;

use Drupal\Core\Cache\CacheableDependencyInterface;
use Drupal\Core\Cache\CacheableJsonResponse;
use Drupal\Core\EventSubscriber\HttpExceptionSubscriberBase;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;

class MymoduleExceptionSubscriber extends HttpExceptionSubscriberBase {

  protected static function getPriority() {
    // handle the exceptions we want for JSON before
    // core subscribers do this with priority -70/-75
    return -69;
  }

  protected function getHandledFormats() {
    return ['json'];
  }

  public function on404(ExceptionEvent $event) {
    /** @var \Symfony\Component\HttpKernel\Exception\HttpExceptionInterface $exception */
    $exception = $event->getThrowable();

    $content = [
      'code' => 60,
      'message' => 'Resource not found',
      'description' => 'The requested URI or the requested resource does not exist.',
    ];
  
    // If the exception is cacheable, generate a cacheable response.
    if ($exception instanceof CacheableDependencyInterface) {
      $response = new CacheableJsonResponse($content, 404, $exception->getHeaders());
      $response->addCacheableDependency($exception);
    }
    else {
      $response = new JsonResponse($content, 404, $exception->getHeaders());
    }

    $event->setResponse($response);
  }

}

mymodule.services.yml

services:
  mymodule.404_subscriber:
    class: Drupal\mymodule\EventSubscriber\MymoduleExceptionSubscriber
    tags:
      - { name: event_subscriber }
3
  • @ 4uk4 : WoW, thanks for this code. It saves me a lot. Let me try it and let you know Commented Jan 13 at 14:49
  • Works perfectly. Only small typo get priority() should be getPriority() Commented Jan 13 at 15:01
  • This was the spell checker when I inserted the comment about priorities.
    – 4uk4
    Commented Jan 13 at 15:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.