Improve error handling
This commit is contained in:
parent
87bd780f9f
commit
e6a8150483
7 changed files with 78 additions and 62 deletions
|
|
@ -5,7 +5,6 @@ import zio.http.*
|
|||
import zio.http.codec.*
|
||||
import zio.http.endpoint.*
|
||||
import zio.schema.*
|
||||
import zio.schema.annotation.discriminatorName
|
||||
|
||||
import lu.foyer.JsonApiResponse.Many
|
||||
import lu.foyer.JsonApiResponse.One
|
||||
|
|
@ -36,15 +35,6 @@ object JsonApiResponse:
|
|||
case class RelationshipsData(id: String, `type`: String) derives Schema
|
||||
case class RelationshipsLinks(related: String) derives Schema
|
||||
|
||||
@discriminatorName("errorType")
|
||||
enum Error derives Schema:
|
||||
case NotFound(id: String)
|
||||
case InternalServerError(title: String)
|
||||
object Error:
|
||||
given Schema[Error.NotFound] = DeriveSchema.gen
|
||||
given Schema[Error.InternalServerError] = DeriveSchema.gen
|
||||
end JsonApiResponse
|
||||
|
||||
final case class ProxyHeaders(
|
||||
protocol: Option[String],
|
||||
host: Option[String],
|
||||
|
|
@ -80,26 +70,26 @@ trait JsonApiController:
|
|||
endpoint: Endpoint[PathInput, Input, ZNothing, ZNothing, AuthType.None]
|
||||
)
|
||||
inline def jsonApiOne[Output: Schema]
|
||||
: Endpoint[PathInput, Input, JsonApiResponse.Error, One[Output], AuthType.None.type] =
|
||||
: Endpoint[PathInput, Input, JsonApiError, One[Output], AuthType.None.type] =
|
||||
jsonApiOneWithStatus(Status.Ok)
|
||||
|
||||
def jsonApiOneWithStatus[Output: Schema](status: Status) =
|
||||
endpoint
|
||||
.out[JsonApiResponse.One[Output]](status)
|
||||
.outErrors[JsonApiResponse.Error](
|
||||
HttpCodec.error[JsonApiResponse.Error.NotFound](Status.NotFound),
|
||||
HttpCodec.error[JsonApiResponse.Error.InternalServerError](Status.InternalServerError)
|
||||
.outErrors[JsonApiError](
|
||||
HttpCodec.error[JsonApiError.NotFound](Status.NotFound),
|
||||
HttpCodec.error[JsonApiError.InternalServerError](Status.InternalServerError)
|
||||
)
|
||||
def jsonApiMany[Output: Schema] =
|
||||
endpoint
|
||||
.out[JsonApiResponse.Many[Output]]
|
||||
.outError[JsonApiResponse.Error](Status.InternalServerError)
|
||||
.outError[JsonApiError](Status.InternalServerError)
|
||||
|
||||
extension [PathInput, Input, Output, Auth <: AuthType](
|
||||
endpoint: Endpoint[PathInput, Input, JsonApiResponse.Error, One[Output], AuthType.None]
|
||||
endpoint: Endpoint[PathInput, Input, JsonApiError, One[Output], AuthType.None]
|
||||
)
|
||||
def implementJsonApiOne[Env, A](
|
||||
f: Input => RIO[Env, Option[A]],
|
||||
f: Input => ZIO[Env, JsonApiError | Throwable, Option[A]],
|
||||
getId: A => String,
|
||||
getEntity: A => Output,
|
||||
onthology: String = this.onthology,
|
||||
|
|
@ -113,11 +103,12 @@ trait JsonApiController:
|
|||
endpoint.implement(input =>
|
||||
for
|
||||
item <- f(input)
|
||||
.mapError(e => JsonApiResponse.Error.InternalServerError(e.getMessage))
|
||||
.flatMap {
|
||||
case Some(paged) => ZIO.succeed(paged)
|
||||
case None => ZIO.fail(JsonApiResponse.Error.NotFound(input.toString))
|
||||
.tapErrorCause(ZIO.logErrorCause(_))
|
||||
.mapError {
|
||||
case e: Throwable => JsonApiError.InternalServerError(e.getMessage)
|
||||
case e: JsonApiError => e
|
||||
}
|
||||
.someOrFail(JsonApiError.NotFound(input.toString))
|
||||
headers <- ZIO.service[ProxyHeaders]
|
||||
yield JsonApiResponse.One(
|
||||
JsonApiResponse.Entity(
|
||||
|
|
@ -146,7 +137,7 @@ trait JsonApiController:
|
|||
)
|
||||
|
||||
def implementJsonApiOneEvent[Env](
|
||||
f: Input => RIO[Env, Option[Event[Output]]]
|
||||
f: Input => ZIO[Env, JsonApiError | Throwable, Option[Event[Output]]]
|
||||
)(implicit trace: Trace
|
||||
): Route[Env & ProxyHeaders, Nothing] =
|
||||
implementJsonApiOne(
|
||||
|
|
@ -168,7 +159,7 @@ trait JsonApiController:
|
|||
end extension
|
||||
|
||||
extension [PathInput, Input, Output, Auth <: AuthType](
|
||||
endpoint: Endpoint[PathInput, Input, JsonApiResponse.Error, Many[Output], AuthType.None]
|
||||
endpoint: Endpoint[PathInput, Input, JsonApiError, Many[Output], AuthType.None]
|
||||
)
|
||||
def implementJsonApiMany[Env, A](
|
||||
f: Input => RIO[Env, Paged[A]],
|
||||
|
|
@ -205,7 +196,8 @@ trait JsonApiController:
|
|||
page = JsonApiResponse.Page(number = 0, size = 10)
|
||||
)
|
||||
))
|
||||
.mapError(e => JsonApiResponse.Error.InternalServerError(e.getMessage))
|
||||
.tapErrorCause(ZIO.logErrorCause(_))
|
||||
.mapError(e => JsonApiError.InternalServerError(e.getMessage))
|
||||
)
|
||||
|
||||
inline def implementJsonApiManyEntity[Env](
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue