首页 文章

Laravel Dingo Api - 如何从API控制器返回JSON格式的错误响应?

提问于
浏览
1

在我的routes.php中,我有这个:

$apiSettings = [
    'version' => 'v1',
    'prefix' => 'api',
    'protected' => true
];   
Route::api($apiSettings, function() {
    Route::get('venue', 'ApiDataController@venue');
});

受保护的场地API路由访问控制器方法 . 控制器方法在Venues模型上执行Eloquent Query,并返回响应 . 这非常有效 . 问题在于,如果我想返回错误 - 我不确定如何 . 这是场地方法:

public function venue(){

    try {
        //Some code that returns an exception
    } catch(someexception $e) {
        //How do I return the exception such that Dingo will parse it into a proper JSON response?
    }
    $response = Venue::with('address')->get();
    return $response;

}

我尝试过的解决方案(在try块中):

try {
    //some code that returns an exception
} catch(someexception $e) {
    $response = array(
        'message' => 'some random exception message'
    );
    return Response::json($response, 403);
}

我尝试这样做时出现以下错误: Argument 1 passed to Dingo\Api\Http\Response::makeFromExisting() must be an instance of Illuminate\Http\Response, instance of Illuminate\Http\JsonResponse given, called in /vagrant/www/planat-app/vendor/dingo/api/src/Routing/Router.php on line 165 and defined

第二次尝试的解决方案:从Dingo的返回错误,文档,我测试了如果我返回其中一个例外会发生什么:

public function venue(){
    throw new Symfony\Component\HttpKernel\Exception\ConflictHttpException('err);
}

但是,不会将错误作为JSON响应返回,而是会出现laravel错误页面,并显示以下错误:

[internal function]: ApiDataController->venue()
#1 /vagrant/www/planat-app/vendor/laravel/framework/src/Illuminate/Routing/Controller.php(231):
call_user_func_array(Array, Array)
#2 /vagrant/www/planat-app/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(93):
Illuminate\Routing\Controller->callAction('venue', Array)
#3 /vagrant/www/planat-app/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(62):
Illuminate\Routing\ControllerDispatcher->call(Object(ApiDataController),
Object(Illuminate\Routing\Route), 'venue')
#4 /vagrant/www/planat-app/vendor/laravel/framework/src/Illuminate/Routing/Router.php(930):
Illuminate\Routing\ControllerDispatcher->dispatch(Object(Illuminate\Routing\Route),
Object(Dingo\Api\Http\InternalRequest), 'ApiDataControll...', 'venue')
#5 [internal function]: Illuminate\Routing\Router->Illuminate\Routing\{closure}()
#6 /vagrant/www/planat-app/vendor/laravel/framework/src/Illuminate/Routing/Route.php(105):
call_user_func_array(Object(Closure), Array)
#7 /vagrant/www/planat-app/vendor/laravel/framework/src/Illuminate/Routing/Router.php(996):
Illuminate\Routing\Route->run(Object(Dingo\Api\Http\InternalRequest))
#8 /vagrant/www/planat-app/vendor/laravel/framework/src/Illuminate/Routing/Router.php(964):
Illuminate\Routing\Router->dispatchToRoute(Object(Dingo\Api\Http\InternalRequest))
#9 /vagrant/www/planat-app/vendor/dingo/api/src/Routing/Router.php(147):
Illuminate\Routing\Router->dispatch(Object(Dingo\Api\Http\InternalRequest))
#10 /vagrant/www/planat-app/vendor/dingo/api/src/Dispatcher.php(337): Dingo\Api\Routing\Router->dispatch(Object(Dingo\Api\Http\InternalRequest))
#11 /vagrant/www/planat-app/vendor/dingo/api/src/Dispatcher.php(278): Dingo\Api\Dispatcher->dispatch(Object(Dingo\Api\Http\InternalRequest))
#12 /vagrant/www/planat-app/vendor/dingo/api/src/Dispatcher.php(213): Dingo\Api\Dispatcher->queueRequest('get', 'venue', Array)
#13 /vagrant/www/planat-app/app/routes.php(51): Dingo\Api\Dispatcher->get('venue')
#14 [internal function]: {closure}()
#15 /vagrant/www/planat-app/vendor/laravel/framework/src/Illuminate/Routing/Route.php(105):
call_user_func_array(Object(Closure), Array)
#16 /vagrant/www/planat-app/vendor/laravel/framework/src/Illuminate/Routing/Router.php(996):
Illuminate\Routing\Route->run(Object(Illuminate\Http\Request))
#17 /vagrant/www/planat-app/vendor/laravel/framework/src/Illuminate/Routing/Router.php(964):
Illuminate\Routing\Router->dispatchToRoute(Object(Illuminate\Http\Request))
#18 /vagrant/www/planat-app/vendor/dingo/api/src/Routing/Router.php(147):
Illuminate\Routing\Router->dispatch(Object(Illuminate\Http\Request))
#19 /vagrant/www/planat-app/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(738):
Dingo\Api\Routing\Router->dispatch(Object(Illuminate\Http\Request))
#20 /vagrant/www/planat-app/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(708):
Illuminate\Foundation\Application->dispatch(Object(Illuminate\Http\Request))
#21 /vagrant/www/planat-app/vendor/dingo/api/src/Http/Middleware/RateLimit.php(97):
Illuminate\Foundation\Application->handle(Object(Illuminate\Http\Request),
1, true)
#22 /vagrant/www/planat-app/vendor/dingo/api/src/Http/Middleware/Authentication.php(102):
Dingo\Api\Http\Middleware\RateLimit->handle(Object(Illuminate\Http\Request),
1, true)
#23 /vagrant/www/planat-app/vendor/laravel/framework/src/Illuminate/Session/Middleware.php(72):
Dingo\Api\Http\Middleware\Authentication->handle(Object(Illuminate\Http\Request),
1, true)
#24 /vagrant/www/planat-app/vendor/laravel/framework/src/Illuminate/Cookie/Queue.php(47):
Illuminate\Session\Middleware->handle(Object(Illuminate\Http\Request),
1, true)
#25 /vagrant/www/planat-app/vendor/laravel/framework/src/Illuminate/Cookie/Guard.php(51):
Illuminate\Cookie\Queue->handle(Object(Illuminate\Http\Request), 1,
true)
#26 /vagrant/www/planat-app/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23):
Illuminate\Cookie\Guard->handle(Object(Illuminate\Http\Request), 1,
true)
#27 /vagrant/www/planat-app/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(606):
Stack\StackedHttpKernel->handle(Object(Illuminate\Http\Request))
#28 /vagrant/www/planat-app/public/index.php(49): Illuminate\Foundation\Application->run()

3 回答

  • 2

    在构建api时,您可以在全局范围内捕获类似的异常类型 . 例如,如果用户试图获取具有不存在的ID的客户,则可以执行此操作 .

    Customer::findOrFail($id);
    

    然后你可以像这样在 app/start/global.php 中捕获所有这种类型的异常 .

    App::error(function(ModelNotFoundException $modelNotFoundException){
        $errorResponse = [
            'errors'    => 'Not found any resource',
            'message'   => $modelNotFoundException->getMessage()
        ];
    
        return Response::json($errorResponse, 404);     //404 = Not found
    });
    
  • 0

    阅读Dingo的Returning Errors文档,它说:

    而不是手动创建和返回错误响应,您可以简单地抛出异常,包将处理异常并返回适当的响应 . 以下是遇到错误时应抛出的所有受支持异常的列表 . Symfony \ Component \ HttpKernel \ Exception \ AccessDeniedHttpException Symfony \ Component \ HttpKernel \ Exception \ BadRequestHttpException Symfony \ Component \ HttpKernel \ Exception \ ConflictHttpException Symfony \ Component \ HttpKernel \ Exception \ GoneHttpException Symfony \ Component \ HttpKernel \ Exception \ HttpException Symfony \ Component \ HttpKernel \ Exception \ LengthRequiredHttpException Symfony \ Component \ HttpKernel \ Exception \ MethodNotAllowedHttpException Symfony \ Component \ HttpKernel \ Exception \ NotAcceptableHttpException Symfony \ Component \ HttpKernel \ Exception \ NotFoundHttpException Symfony \ Component \ HttpKernel \ Exception \ PreconditionFailedHttpException Symfony \ Component \ HttpKernel \ Exception \ PreconditionRequiredHttpException Symfony \ Component \ HttpKernel \ Exception \ ServiceUnavailableHttpException Symfony \ Component \ HttpKernel \ Exception \ TooManyRequestsHttpException Symfony \ Component \ HttpKernel \ Exception \ UnauthorizedHttpException Symfony \ Component \ HttpKernel \ Exception \ UnsupportedMediaTypeHttpException

    它还支持一些通用资源异常,您也可以将验证错误传递到:

    Dingo \ Api \ Exception \ DeleteResourceFailedException Dingo \ Api \ Exception \ ResourceException Dingo \ Api \ Exception \ StoreResourceFailedException Dingo \ Api \ Exception \ UpdateResourceFailedException

    所以简而言之,你需要抛出一个上面的例外,Dingo支持回到Dingo . 例如:

    try {
        //Some code that returns an exception
    } catch(SomeException $e) {
        throw new Symfony\Component\HttpKernel\Exception\HttpException($e->getMessage);
    }
    

    或者实际上,如果抛出的异常是上面的类型之一,或者扩展它们的异常,你可以完全删除你的try / catch子句 . 异常应该自动抛回Dingo来处理它 .

  • 2

    请检查一下:

    try {
        //some code that returns an exception
    } catch(\Exception $e) {
        $response = array(
            'message' => 'some random exception message'
        );
        return response()->json($response, 403);
    }
    

    请检查并让我知道 .

相关问题