【问题标题】:Laravel Exception Handling - How to handle exceptions with both API and HtmlLaravel 异常处理 - 如何使用 API 和 Html 处理异常
【发布时间】:2013-09-30 21:10:12
【问题描述】:

API 调用

http://localhost:8888/api/v1/users/100 //doesn't exist

HTML 调用

http://localhost:8888/admin/users/100 //doesn't exist

显然,我不希望 Html Call 异常返回 json 数据,也不希望 Api Call 返回 Html 数据。

我不是控制器中的异常处理。我在我的 UserRepository 中处理异常。因此,我的控制器只是从用户存储库返回结果。

class Sentry2UserRepository implements UserInterface {
public function findById($id) {
    try {
        return Sentry::findUserById($id);
    }
    catch (\Cartalyst\Sentry\Users\UserNotFoundException $e) {
    // Do something here
    return false;
        }
}
}

问题 1:将错误传递回控制器以便它知道要显示什么的正常/正确方法是什么?

问题2:异常/错误是否有标准的json API格式?

问题 3:Web UI 使用内部 JsonApi 是一种好习惯吗?还是我目前使用 WebUi 控制器查询与 Api 相同的存储库以正确的方式做事?

【问题讨论】:

    标签: exception-handling laravel laravel-4


    【解决方案1】:

    在你的 filters.php 中试试这个魔法:

    App::error(function(Exception $exception, $httpCode)
    {
        if (Request::is('api/*')){
             return Response::json( ['code' => $exception->getCode(), 'error' => $exception->getMessage()], $httpCode );
        }else{
             $layout = View::make('layouts.main');
             $layout->content = View::make('errors.error')->with('code', $exception->getCode())->with('error', $exception->getMessage())->with('httpCode',$httpCode);
             return Response::make($layout, $httpCode);
        }
    });
    

    【讨论】:

      【解决方案2】:

      首先,我觉得你在Sentry2UserRepository的做法还不错,没关系,IMO

      问题 1:传回错误的正常/正确方法是什么 到控制器,以便它知道要显示什么?

      好吧,IMO,根据应用程序,您应该确定应该如何处理异常。您提到了so that it will know what to display,在这种情况下,这取决于您需要从异常中获取的信息以及在异常发生后采取下一步行动的方式和信息。现在,如果您需要错误消息,那么您可以返回return $e->getMessage(),这样您就可以确切地知道实际发生了什么。有很多方法可以做到这一点,例如,使用单个 catch

      try{
          // ...
      }
      catch( Exception $e )
      {
          if ($e instanceof UserNotFoundException) {
              // it's an instance of UserNotFoundException, return accordingly
          }
          elseif ($e instanceof SomethinElseException) {
              // it's an instance of SomethinElseException, return accordingly
          }
      }
      

      此外,您可以使用不同的自定义异常类,并且可以使用多个 catch 块,即

      class AnException extends Exception 
      {
          public function customErrorMessage() 
          {
              return `AnException occurred!`
          }
      }
      
      class AnotherException extends Exception 
      {
          public function customErrorMessage() 
          {
              return `AnotherException occurred!`
          }
      }
      

      然后使用多个catch 块捕获,即

      try 
      {
          // ...
      }
      
      catch(AnException $e) 
      {
          return $e->customErrorMessage();
      }
      
      catch(AnotherException $e) 
      {
          return $e->customErrorMessage();
      }
      catch(Exception $e)
      {
          return $e->getMessage();
      }
      

      问题2:异常/错误是否有标准的json API格式?

      问题 3:Web UI 使用内部 JsonApi 是一种好习惯吗?还是我目前使用 WebUi 控制器查询与 Api 相同的存储库以正确的方式做事?

      实际上我不知道这样的api,而且你做得对,IMO。这是因为,你有这个

      class Sentry2UserRepository implements UserInterface {
          public function findById($id) {
              try {
                  return Sentry::findUserById($id);
              }
              catch (\Cartalyst\Sentry\Users\UserNotFoundException $e) {
                  // Do something here
                  return false;
              }
          }
      }
      

      因此,可以在控制器中编写类似这样的代码

      if(findById(5)) {
          // found and dump it to the view
      }
      else {
          // show "Not Found !", false will be back only for UserNotFoundException 
      }
      

      但是,如果你在 UserNotFoundException 捕获中有这个

      return $e; // or anything else (maybe an array containing status and message)
      

      那么就不能写这么简单的代码了

      if(findById(5)) {
          // found and dump it to the view
      }
      

      因为,对于数组的$e object oe,is 语句为 true,因此您必须再次检查它,使用类似这样的 somrthing

      $result = findById(5);
      if($result && $result->code && $result->code === 0) {
          // something according to code
      }
      

      或者,也许是这样的

      if($result && $result->code) {
          // error happened, now determine the code
          switch($result->code){
              case 0:
              // show message
              break;
      
              case 1:
              // show message
              break;
          }
      }
      

      所以,IMO,为什么,您需要向用户展示您的应用程序中发生了什么错误,为什么不只是向状态,无论是您获得数据还是未获得数据。是不是很简单?只需KISS。这只是我的意见,仅此而已。

      【讨论】:

        猜你喜欢
        • 2015-02-18
        • 2014-04-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多