0

我正在寫Scala的微服務,我正在處理來自服務器的響應,通過拋出不同的異常來處理錯誤。如何通過一個例外,在默認的「原因」作爲函數參數斯卡拉

錯誤處理對於每個錯誤基本相同,記錄警告消息並拋出異常。唯一改變的是我生成的自定義異常,所以我不想在我的「case」語句中重複相同的代碼,因此我決定使用一個方法,接受異常作爲參數。

config.httpClient.apply(request).map(response => { 
    response.getStatusCode() match { 
    case Status.Ok.code => 
     <Do stuff to process the response> 
    case Status.BadRequest.code => 
     errorReporting(response.status.code, response.contentString, BadRequestException) 
    case Status.Unauthorized.code => 
     errorReporting(response.status.code, response.contentString, UnauthorizedException) 
    case _ => 
     errorReporting(response.status.code, response.contentString, GeneralException) 
    } 
}) 

例外被定義爲case類:

case class GeneralException(private val message: String, 
          private val cause: Throwable = None.orNull) extends Exception (message, cause) 

case class BadRequestException(private val message: String, 
           private val cause: Throwable = None.orNull) extends Exception(message, cause) 

case class UnauthorizedException(private val message: String, 
           private val cause: Throwable = None.orNull) extends Exception(message, cause) 

而且ERRORREPORTING方法在這裏:

def errorReporting(errorCode: Int, errorMessage: String, ex: (String, Throwable) => Throwable) = { 
    val message = s"Auth server response code: ${errorCode}, " + errorMessage 
    warn(message) 
    throw ex(message, None.orNull) 
} 

我與 「事業」 定義默認值我的異常。問題是,我沒有找到一種方法來告訴「errorReporting」Throwable是一個可選參數,因此我不得不拋出異常throw ex(message, None.orNull),我不覺得很優雅。

此條目Invocation of methods with default parameters in scala higher-order function告訴我不能將默認參數傳遞給高階函數。

有沒有其他方法可以更好地解決這個問題?

+0

的情況下,也許這個問題是有用的給你:https://stackoverflow.com/questions/11982474/case-classes-with-optional-fields- in-scala/11982762 –

+0

'None.orNull'是編寫'null'的好方法。對於可選參數,使用'cause:Option [Throwable] = None' –

+0

@ T.Grottker沒有解決我的問題,仍然有用。謝謝! – Visiedo

回答

1

您可以在自定義特徵中指定默認參數。您的異常類的伴隨對象可以擴展該特徵,因此它們也會獲得默認參數。請注意,在這種情況下,您不需要在類定義內使用默認參數。

接下來,只要你的函數接受特質

// Extends clause is optional, tho without it you lose 
// methods like "compose" on companion 
trait OptionalCauseConstructor extends ((String, Throwable) => Exception) { 
    def apply(message: String, cause: Throwable = null): Exception 
} 

case class GeneralException(private val message: String, 
          private val cause: Throwable) extends Exception (message, cause) 

// autogenerated apply matches required signature, so implementation is automatic 
object GeneralException extends OptionalCauseConstructor 


case class BadRequestException(private val message: String, 
           private val cause: Throwable) extends Exception(message, cause) 

object BadRequestException extends OptionalCauseConstructor 

// etc... 


def raiseError(ctor: OptionalCauseConstructor) = { 
    val cause = ctor("cause") // cause is default 
    throw ctor("foo", cause) // cause is supplied 
} 

raiseError(GeneralException) 
// also, Scala 2.12 allows for SAM implementation 
raiseError(new Exception(_, _)) 
相關問題