2013-09-30 21 views
4

API調用Laravel異常處理 - 如何處理與這兩個API和HTML例外

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

的Html呼叫

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

很顯然,我不希望在HTML調用異常返回JSON數據和我不希望Api調用返回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查詢相同的存儲庫?

回答

0

首先,我覺得你的方法在Sentry2UserRepository也不錯,沒關係,IMO

問題1:什麼是正常/正確的方式將錯誤傳回給控制器,以便它知道要顯示什麼?

那麼,國際海事組織,取決於應用程序,你應該確定如何處理異常。您提到了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:有沒有斯坦dard 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對象OE爲一個數組,所以你必須檢查一遍,用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。這只是我的看法,就是這樣。

3

試試這個奇蹟在你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); 
    } 
});