Errors and Exceptions
When error occurs in GraphQL, the server adds an errors
entry in the response. Here is an example
{
"errors": [
{
"message": "Wished price was not found by id: some-id",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"wishedPrice"
]
}
]
}
You can read more about GraphQL errors in the official spec.
In most cases the HTTP status code will also reflect the error condition. So for example it will be 404
in case something was not found.
Exceptions in your module
The graphql-base
module provides the following exceptions you can use or extend from
Class |
Category |
Description |
HTTP Status code |
---|---|---|---|
InvalidLogin |
permissionerror |
Thrown when we have an invalid login |
401 |
InvalidToken |
permissionerror |
Thrown when a token is invalid |
403 |
NotFound |
requesterror |
Thrown when a record was not found |
404 |
Exists |
requesterror |
Thrown when a record exists (when we want to register already registered customer) |
400 |
OutOfBounds |
requesterror |
Thrown when values are out of bounds |
400 |
Exception to GraphQL Error
The GraphQL modules are build using GraphQLite, which requires graphql-php. Here you can see how graphql-php handles errors.
In short: If you want the consumer to see the message of your exception, it needs to implement the GraphQL\Error\ClientAware
interface.
HTTP Status code
If you want to change the HTTP status code in your custom exception, you have to implement OxidEsales\GraphQL\Base\Exception\HttpErrorInterface
Error categories
In the error response you might want to see a category
entry, which describes the category of the error. You can use OxidEsales\GraphQL\Base\Exception\ErrorCategories
class, which defines several error categories.
Example
Here is an example of a custom exception which tells us that a product was not found. It is part of the graphql-storefront
module.
<?php
declare(strict_types=1);
namespace OxidEsales\GraphQL\Storefront\Product\Exception;
use OxidEsales\GraphQL\Base\Exception\NotFound;
use function sprintf;
final class ProductNotFound extends NotFound
{
public static function byId(string $id): self
{
return new self(sprintf('Product was not found by id: %s', $id));
}
}
Here is an example of an exception when customer’s password does not match the requirements:
<?php
declare(strict_types=1);
namespace MyVendor\MyModule\Record\Exception;
use Exception;
use GraphQL\Error\ClientAware;
use OxidEsales\GraphQL\Base\Exception\ErrorCategories;
use OxidEsales\GraphQL\Base\Exception\HttpErrorInterface;
final class PasswordMismatchException extends Exception implements ClientAware, HttpErrorInterface
{
public function getHttpStatus(): int
{
return 403;
}
public function isClientSafe(): bool
{
return true;
}
public function getCategory(): string
{
return ErrorCategories::REQUESTERROR;
}
public static function byOldPassword(): self
{
return new self('Old password does not match our records');
}
public static function byLength(): self
{
return new self('Password does not match length requirements');
}
}
In this example you can see the usage of ClientAware
, HttpErrorInterface
and ErrorCategories
.