Hi there!
I wanted to add business logic error logging to my service.
I was thinking of implementing logging at the interceptor level, but I ran into the problem that it is impossible to get error information at the interceptor level.
I have something like this endpoint:
val myEndpoint =
endpoint
.in(
header[SiebelId]("siebel-id")
)
.in(
query[String]("appVersion").description("example - 5.18") and
query[String]("platform").description("ios or android") and
query[String]("deviceId").description("unique id of device")
)
.errorOut(
oneOf(
oneOfVariant(jsonBody[InternalServerErrorResponse] and statusCode(StatusCode.InternalServerError)),
oneOfVariant(jsonBody[BadRequestResponse] and statusCode(StatusCode.BadRequest))
)
)
.in("api" / "v1" / "mb")
.get
.in("phones")
.out(jsonBody[PhonesResponseRaw])
.description("List of user's phones")
.zServerLogic {
case (_, siebelId, _, _, _) => handler.getConnectedPhones(MbChatId(siebelId.value))
}
And here is such a handler:
def getConnectedPhones(siebelId: MbChatId): IO[InternalServerErrorResponse, PhonesResponseRaw] =
for {
basicAuth <- authService.getAuth
phones <- secretariesService.getPhones(basicAuth, siebelId).mapError(_ => InternalServerErrorResponse("some additional info"))
} yield PhonesResponseRaw(phones)
If ZIO fails with an error that the endpoint did not expect, then ServerLog.exception will be called for it, where you can log the error. But if ZIO fails with an error that is defined in .errorOut, then the request is considered successfully processed and error information cannot be received.
It would be possible to remove .errorOut and force the handler to return Task[A], but I don’t want to lose typing.
Is there a way at the interceptor level to understand that the effect ended with an Error exception? Or maybe there is some other approach to error logging?