tl;dr: What should I do (how to configure my “api” app) to get JSON-formatted response (as told in the guide) and 404 Not Found error code:
{
"name": "Not Found Exception",
"message": "The requested resource was not found.",
"code": 0,
"status": 404
}
Because right now, all I am getting is either empty response body with 404 Not Found code or my application crashes and responds with 500 Internal Server Error instead.
In my “api” application I have controllers for my models/endpoints only, so I don’t have /api/controllers/SiteController.php. Naturally, I don’t have actionError method as well (since I don’t have a controller at all). This causes that when calling a non-existing endpoint, instead of JSON-formatter response, I am getting a raw exception:
An Error occurred while handling another error:
yii\base\InvalidRouteException: Unable to resolve the request "site/error". in (...)\vendor\yiisoft\yii2\base\Module.php:561
Stack trace:
#0 (...)\vendor\yiisoft\yii2\web\ErrorHandler.php(109): yii\base\Module->runAction('site/error')
#1 (...)\vendor\yiisoft\yii2\base\ErrorHandler.php(152): yii\web\ErrorHandler->renderException(Object(yii\web\NotFoundHttpException))
Bad! :[
Trying to resolve it, I have created SiteController and added configuration inside it:
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::class,
'rules' => [
[
'actions' => ['error'],
'allow' => true,
],
],
],
];
}
public function actions()
{
return [
'error' => [
'class' => \yii\web\ErrorAction::class,
],
];
}
This time this ends with exception that a view (required by \yii\web\ErrorAction
is not found):
An Error occurred while handling another error:
yii\base\ViewNotFoundException: The view file does not exist: C:\XAMPP\htdocs\akademia-slaska\tcmed-platform-web\api\views\site\error.php in C:\XAMPP\htdocs\akademia-slaska\tcmed-platform-web\vendor\yiisoft\yii2\base\View.php:233
Also bad.
I’ve digged into guide to find:
When handling a RESTful API request, if there is an error in the user request or if something unexpected happens on the server, you may simply throw an exception to notify the user that something went wrong. If you can identify the cause of the error (e.g., the requested resource does not exist), you should consider throwing an exception along with a proper HTTP status code (e.g., yii\web\NotFoundHttpException represents a 404 status code).
So, I have removed actions()
method and replaced it with actionError()
method instead:
public function actionError()
{
throw new NotFoundHttpException('Boo!');
}
Not much change to be honest, another nasty exception, this time:
An Error occurred while handling another error:
yii\web\NotFoundHttpException: Boo! in C:\XAMPP\htdocs\akademia-slaska\tcmed-platform-web\api\controllers\SiteController.php:46
Something (but what) told me to keep actionError()
empty:
public function actionError()
{
}
Finally, I am getting a correct response (my remote client finally gets 404 Not Found instead of 500 Internal Server Error). But with empty body (my client says “No body returned for response”) and marks that it received 0 bytes response.
In none of my voyages I managed to get to the result “promised” by the guide, i.e. getting correct error handling with JSON-formated error data in the body:
HTTP/1.1 404 Not Found
Date: Sun, 02 Mar 2014 05:31:43 GMT
Server: Apache/2.2.26 (Unix) DAV/2 PHP/5.4.20 mod_ssl/2.2.26 OpenSSL/0.9.8y
Transfer-Encoding: chunked
Content-Type: application/json; charset=UTF-8
{
"name": "Not Found Exception",
"message": "The requested resource was not found.",
"code": 0,
"status": 404
}
What am I missing or doing wrong?
And the most important – why do I need SiteController at all? Why doesn’t Yii handle non-existing endpoints gracefully, i.e. returning 404, instead of 500?