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(_, _)) 
相关问题