Need to add some info in thrown exception

Hello
When I throw a custom exception in my Api, how can I insert additional info?

My custom exception:

class PermissionException extends Exception
{
    protected $permissionResource;
    public function __construct($message, $code = 403, $resource = null)
    {
        parent::__construct($message, $code);
        $this->permissionResource = $resource;
    }
    public function getPermissionResource()
    {
        return $this->permissionResource;
    }
}

I am using

   throw new PermissionException('Connection refused', 403, ['id' => 123]);

Where should I call getPermissionResource() so that my additional info (id) gets injected in response in addition of message, code, …?

Thank’s for help

You will need to catch and handle that custom exception somewhere. The standard code knows nothing about this and cannot do anything with it. Where you need to handle the exception will very much depend on the structure of your application and what you’re hoping to do with this data. For example, if it’s in an API response, that’s going to be different than on a web page.

I agree with you.
My problem is to insert my info into my API response when I throw an exception in addition of message, code, url, etc…

How is your system currently generating API responses in exception cases?

For example : throw new BadRequestException(“Bad request”, 403);

In my case : throw new PermissionException(“message”, 403, [‘id’=>123, ‘post_id’=>456]);

Right, but how does the system handle that when it comes to creating the response string that it sends back to the client? I’m not sure I’m explaining this well.

You throw an exception. Various things happen in the code after that. At some point, you send a response (JSON formatted, maybe, or maybe not, you haven’t said, and it doesn’t really matter), presumably with error details in it. You’ve said that you want to inject your additional info into that response, so there must be some response happening, with e.g. your “Connection refused” string in it.

What I’m getting at is how that actual response string is currently being generated. What code (whether yours or a plugin) is mashing together details in the exception to make a string that’s useful to send to the client that made the faulty request? Your changes will need to happen somewhere in that vicinity. Without knowing anything at all about how it’s currently happening, we can’t give any specifics about how to change it.

Looks like you need to look at extending your ErrorTrap / Handling with something customized that can call and format getPermissionResource()

https://book.cakephp.org/5/en/development/errors.html#custom-error-rendering

I finally found myself how to do thanks to jmcd73 who guided me to the way…

In fact I needed a custom exception renderer as explained in the Cakephp doc but too quicly and not very clear.

What I did:
in app.php, activate my custom renderer

'Error' => [
  'exceptionRenderer' => 'App\Error\AppExceptionRenderer',
.../...

In my /src/Error/AppExceptionRenderer.php created a function with the same name as my exception: ie connection

<?php

namespace App\Error;

use Cake\Core\Configure;
use Cake\Error\Renderer\WebExceptionRenderer;
use Cake\Core\Exception\CakeException;

class AppExceptionRenderer extends WebExceptionRenderer
{
    public function connection($exception)
    {
        assert($exception instanceof \App\Exception\ConnectionException);

        /** @var \App\Exception\ConnectionException $exception */
        $message = $exception->getMessage();
        $url = $this->controller->getRequest()->getRequestTarget();
        $code = $exception->getCode();
        $info = $exception->getConnectionResource();

        $response = $this->controller->getResponse();

        $viewVars = [
            'message' => $message,
            'url' => h($url),
            'code' => $code,
            'info' => $info,
        ];
        $serialize = ['message', 'url', 'code', 'info'];

        $isDebug = Configure::read('debug');
        if ($isDebug) {
        }
        $this->controller->set($viewVars);
        $this->controller->viewBuilder()->setOption('serialize', $serialize);

        if ($exception instanceof CakeException && $isDebug) {
            $this->controller->set($exception->getAttributes());
        }

        $response = $response
            ->withStatus($code, $message)
            ->withStringBody(json_encode($viewVars));
        $this->controller->setResponse($response);

        return $response;
    }
}

I can now throw my exception anywhere in my code like so:

thow new ConnectionException('Wrong credential', 403, ['id'=>123,'name'=>'John Doe'];

And i can see my info in the response (Chrome’s console) and in my application in the xhr response.

Thanks guys