问题
Suppose I need to call a remote JSON/HTTP service. I make a JSON request, send it by HTTP to the server, and receive and parse the JSON response.
Suppose I have data type MyError
for errors and all my functions return Either[MyError, R]
type Result[A] = Either[MyError, A]
def makeJsonRequest(requestData: RequestData): Result[String] = ...
def invoke(url: URL, jsonRequest: String): Result[String] = ...
def parseJsonResponse(jsonResponse: String): Result[ResponseData] = ...
I can combine them to write a new function:
def invokeService(url: URL, requestData: RequestData) Result[ResponseData] = for {
jsonRequest <- makeJsonRequest(requestData).right
jsonResponse <- invoke(url, req).right
responseData <- parseJsonResponse(jsonResponse).right
} yield responseData
Now what if parseJsonResponse
fails ?
I get the error but I need also the whole context. That is I need url
, requestData
, and jsonRequest
. How would you suggest me do it ?
回答1:
If this is a specific case I would make MyError
into a trait (ADT), and allow one of the possible values to be JsonParsingFailed(jsonRequest, ...)
.
If it's something more generic I might use Writer
(or rather type MyWriter[A] = Writer[Vector[MyLogEntry], A]
and then use EitherT[MyWriter, MyError, A]
) to "log the event" at every stage.
来源:https://stackoverflow.com/questions/26657808/error-context-in-error-handling-in-scala