0

私はScalaでマイクロサービスを作成しています。異なる例外を投げてエラーを処理するサーバからの応答を処理しています。Scalaの関数パラメータとしてデフォルトの "cause"を持つ例外を渡す方法

エラー処理は、エラーごとに基本的に同じですが、警告メッセージを記録して例外をスローします。唯一変わるのは私が生成しているカスタム例外の種類なので、 "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 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(_, _)) 
関連する問題