Custom error responses

Hi,
I’m struggling to figure out how to send back an error message when something goes wrong during a request.
I have the following endpoint:

case class ErrorResponse(message: String)
case class CreatedDid(did: String)
val createKeyDid: PublicEndpoint[Unit, Unit, CreatedDid, Any] = endpoint.get
.in(“did” / “create-key”)
.out(
jsonBody[CreatedDid]
)

val createKeyDidServerEndpoint: ServerEndpoint[Any, IO] =
createKeyDid.serverLogicSuccess(_ =>

  val requestBody = KeyCreateDidRequestNew(method = "key")
  val url = Uri.parse(AppConfig.ssiKitCoreUrl ++ "/v1/did/create").getOrElse(uri"http://127.0.0.1:7000/v1/did/create")
  val response = client.send(basicRequest.post(url).body(requestBody).contentType("application/json"))

  if (response.code == StatusCode.Created) {
    println(s"Created did:key: ${response.body}")
    IO.pure(CreatedDid(did = response.body.getOrElse("Problem reading did from response body")))
  } else {
    throw new Exception("Problem creating key did")
  }
)

Instead of an exception like I’m throwing there, I would like to send back a ErrorResponse with a message.

What is the best way to do this?

I think adding an error output using .errorOut should do the trick:

  val createKeyDid: PublicEndpoint[Unit, Unit, CreatedDid, Any] = endpoint.get
    .in("did" / "create-key")
    .out(jsonBody[CreatedDid])
    .errorOut(jsonBody[ErrorResponse])

  val createKeyDidServerEndpoint: ServerEndpoint[Any, IO] =
    createKeyDid.serverLogic(_ =>
      val requestBody = KeyCreateDidRequestNew(method = "key")
      val url = Uri.parse(AppConfig.ssiKitCoreUrl ++ "/v1/did/create").getOrElse(uri"http://127.0.0.1:7000/v1/did/create")
      val response = client.send(basicRequest.post(url).body(requestBody).contentType("application/json"))

      if (response.code == StatusCode.Created) {
        println(s"Created did:key: ${response.body}")
        IO.pure(Right(CreatedDid(did = response.body.getOrElse("Problem reading did from response body"))))
      } else {
        IO.pure(Left("Problem creating key did"))
      }
    )

Also note that for the server logic, you should then use .serverLogic, not .serverLogicSuccess (which can’t signal errors), and wrap the result in a Left/Right.

See also the error handling docs

1 Like

Ah thank you! My main issue was I tried it with .serverLogicSuccess instead of .serverLogic.
Your answer helped a lot!