2014-03-13 26 views
0

我驗證了我的函數,如果在驗證過程中拋出一個異常,我希望在catch和return中停止該方法,由於某種原因,它會繼續並且只能在主嘗試中捕獲/抓住。爲什麼scala在Catch中沒有完成功能

代碼:

def updateProduct(request: UpdateProductRequest): BaseResponse[String] = 
{ 
    try 
    { 
     try 
     { 
      ValidateUpdateProductRequest(request) 
     } 
     catch 
     { 
     case ex: Exception => { 
      val errorResponse:ErrorResponse[String] = ErrorResponse(ErrorCode.InvalidParameters, ex.getMessage, 500) 
      errorResponse // <=- This does not return from function.. In debug i get here 
     } 
     } 
     val deleteProductResult = productRepository.updateProduct(request) //I dont want to get here !! 
     DTOResponse(deleteProductResult) 
    } 
    catch 
    { 
    case ex: Exception => { 
     Logger.error("Failed to update product Id = " +request.product.id, ex); 
     var errorResponse:ErrorResponse[String] = ErrorResponse(ErrorCode.GeneralError, ex.getMessage, 500) 
     errorResponse 
    } 
    } 
} 

我明白階的函數的最後一行是唯一的地方函數將返回,讓我怎麼從抓回來嗎?
原因是我想使用在BaseResponse [字符串]

由於不同錯誤代碼

+0

愚蠢的問題,但你肯定會拋出一個異常在你的'ValidateUpdateProductRequest'方法嗎?這可能是因爲你傳入的主要'catch'是因爲另一個異常,例如在'updateProduct'中發生了... –

+0

是的,我一步一步地調試它,我越來越接近第二次嘗試..但函數不返回,它繼續val val deleteProductResult = productRepository.updateProduct(..),然後得到空引用,因爲產品爲空 - 這就是驗證的一部分.. – ilansch

回答

1

只要您有一個內部表達式要傳播到最外層作爲結果,您可以將其分配給外部表達式中的臨時變量,也可以使用return。因此,舉例來說:

def foo: Int = { 
    try { bar } 
    catch { case ikte: IKnowTheAnswerException => return 42 } 
    lotsOfMath 
} 

def foo: Int = { 
    val iKnowIt = { 
    try { bar } 
    catch { case ikte: IKnowTheAnswerException => Some(42) } 
    } 
    iKnowIt.getOrElse(lotsOfMath) 
} 

即使第二模式似乎白白羅嗦,記住,跳出方法與return並不總是顯而易見的,尤其是在較長的方法。因此,第二種方法在某些情況下可以更清晰地閱讀(特別是當您知道預期模式時)。

+0

我明白返回功能的中間不是「最佳實踐」,甚至違背了scala的原則..所以我認爲我應該儘量避免它 – ilansch

+0

@ilansch - 你應該編寫能夠儘可能乾淨清晰地解決問題的代碼。這可能意味着使用'return'!只要知道有一個替代模式(我的第二個例子),可以有優勢。 –

+0

也許你可以協助:http://stackoverflow.com/questions/22381645/how-to-break-rest-controller-that-return-action-in-scala-play-framework非常感謝。 – ilansch