julien nascimento
julien nascimento

Reputation: 150

How to handle custom errors in webonyx/graphql-php?

I'm creating some graphql queries using webonyx/graphql-php and the documentation is very incomplete explaining how to handle custom errors during a resolving of a query. For example, if the user app send a query looking for some record, I would like to return a custom error "Customer not found", not only this ugly structure

[
    'debugMessage' => 'Actual exception message',
    'message' => 'Internal server error',
    'category' => 'internal',
    'locations' => [
        ['line' => 10, 'column' => 2]
    ],
    'path' => [
        'listField',
        0,
        'fieldWithException'
    ],
    'trace' => [
        /* Formatted original exception trace */
    ]
];

I read a lot of times the docs (https://webonyx.github.io/graphql-php/error-handling/) but cant understand how to do it. Could you help me please?

Thank you!

Upvotes: 1

Views: 2094

Answers (2)

Vengadesh R
Vengadesh R

Reputation: 54

For generating a custom error message you can move on with one of the method below,

Let your schema declaration be like :-

$schema = new Schema(['query' => --your queries-- , 'mutation' => --your mutations-- , ......]);

$result = GraphQL::executeQuery($schema, $requestQuery);

To convert the graphql object into array structure add the steps below:

$result->toArray();

if (!empty($result['errors'])) {
   $result = ['errors' => [['message' => $result['errors'][0]['message']]]];
}

For returning custom error message from Graphql object add the codes below and skip the object to array conversion steps,

if (!empty($result->errors)) {
   $result = ['errors' => [['message' => $result->errors[0]->getMessage()]]];
    
    // The getMessage() method will always be in the 0th index of the errors object
}

Add the lines below for returning the response:-

header('Content-Type: application/json');
echo json_encode($result);

You can generate your error message inside your function like:-

use GraphQL\Error\Error;

$mysqli = new mysqli("localhost","my_user","my_password","my_db");

$result = $mysqli -> query("SELECT * FROM customer_table where id='1'")

if(empty($result)) 
  {
     throw new Error("Customer not found.");
  }

You can have the response structure like below:-

{
"errors": [
    {
        "message": "Customer not found."
    }
]
}

Upvotes: 4

Francis Eytan Dortort
Francis Eytan Dortort

Reputation: 1447

The documentation states that in order to customize the response sent when an exception is thrown, one needs to throw a custom Exception class that implements the interface ClientAware and returns true in the isClientSafe method.

That is to say that you would need to declare an Exception class as follows:

class CustomerNotFound extends \Exception implements ClientAware
{
  protected $message = 'Customer not found';

  public function isClientSafe()
  {
      return true;
  }

  public function getCategory()
  {
      return 'missing';
  }
}

and in your application logic, when no customer record is found, throw the above exception class, similar to:

if ($rowCount < 1)
{
  throw new CustomerNotFound;
}

Upvotes: 3

Related Questions