您将如何使用Laravel处理不同路由的不同错误响应

时间:2014-02-07 21:25:38

标签: php laravel laravel-4

我设置了Laravel路线,如下例所示:

Route::group(array('domain' => 'example.com'), function()
{
    Route::get('/', array('as' => 'root.index', 'uses' => 'RootController@Index'));
    [...]
});

Route::group(array('domain' => 'api.example.com'), function()
{
    Route::when('*', 'ApiFilter');
    Route::get('/', array('as' => 'api.index', 'uses' => 'ApiController@Index'));
    [...]
});

现在,当涉及响应有错误的请求(例如404,403,500等)时,Laravel使用App::error及其相关方法提供了一个很好的解决方案。

我希望以不同的方式响应错误,具体取决于请求是针对root用户还是api域。

我可以使用App::error吗?

希望这是有道理的。

由于

3 个答案:

答案 0 :(得分:1)

是的,你可以这样做。只需要从异常处理程序中的$exception对象获取请求对象,例如,如果你有这样的异常处理程序:

App::error(function(Exception $exception, $code)
{
    $request = $exception->getTrace()[0]['args'][0];
    $path = $request->path(); // will return path without domain, i.e. user/1
    // Take some action depending on the $path
});

现在,根据路径,您可以采取行动。您可以使用Request类的任何公开方法,例如if($request->is('admin/*'))$request->url()来获取包含域名的完整网址。

答案 1 :(得分:1)

您还可以使用内容协商(Accept请求标头或以.json / .xml为后缀的网址)进行不同的错误格式设置,如下所示:

App::error(function(Exception $exception, $code)
{
    if (!preg_match("@text/html@", Request::header('Accept')))
    {
        return Response::json
        (
            array("error" => array("message" => $exception->getMessage())),
            $code
        );
    }
});

如果请求标头Accept不包含text/html,则会导致错误以JSON形式返回。

所以..如果您使用浏览器访问api.yoursite.com - 您仍会看到带有堆栈跟踪和完整详细信息的默认HTML错误页面,因为浏览器将发送Accept: text/html

否则,如果未设置Accept标头或未明确包含text/html,则错误将格式化为JSON。

或者,您可以使用preg_match代替Request::wantsJson()来检测请求的内容格式。

或者,如果您绝对需要/想要分离API逻辑并通过子域路由..:

App::error(function(Exception $exception, $code)
{
    if (preg_match("@^https?://api\.@", Request::url())) /* Or, if not using sub-domain: Request:is("api/*") */
    {
        return Response::json
        (
            array("error" => array("message" => $exception->getMessage())),
            $code
        );
    }
});

答案 2 :(得分:0)

我会对每个路由组应用单独的过滤器,然后在每个过滤器中指定错误处理事件。