CLOVIS
12/27/2022, 4:31 PMEither
for failures, what do kind of data do you store? So far, I'm working on a fairly small project where I just store the kind of error (authentication, validation…) and a String message, but I feel like that won't scale as a more general solution.
Any guidelines/recommendations?chiroptical
12/27/2022, 4:36 PMAuthenticationErrors
which describe the errors and store w/e information you deem necessary for a later inspection.chiroptical
12/27/2022, 4:37 PMCLOVIS
12/27/2022, 4:51 PMchiroptical
12/27/2022, 5:02 PMtoHuman
like function that produces a human readable version of the error.CLOVIS
12/27/2022, 5:03 PMchiroptical
12/27/2022, 5:04 PMJasonB
12/27/2022, 5:04 PMchiroptical
12/27/2022, 5:05 PMCLOVIS
12/27/2022, 5:05 PMCLOVIS
12/27/2022, 5:06 PMmitch
12/28/2022, 12:14 AMRatelimited(val retryAfter: Duration) : PatchUserFailure()
left with a particular retriable after information. This can be consumed by the caller to make informed decisions on how might it retry the call. We don't usually do this everywhere but this is useful for some heavy processes or important / sensitive microservices that are easily overloaded, where we can decide to defer the process to be either retried or to be eventually consistent using rate controlled queues.
Another example would be a service layer returning data class UserAlreadyExists(existingUser: User) : CreateUserFailure()
left when trying to create a user.mitch
12/28/2022, 12:41 AM(DomainFailure) -> FailureResponse
Some have Loggable<T>
typeclass implemented separately and called via extension function on the class fun DomainFailure.loggableJson(): Loggable<T>
to help transform them into a privacy safe loggable json as appropriate.mitch
12/28/2022, 12:48 AMgildor
12/28/2022, 3:09 AMmitch
12/28/2022, 12:58 PMmitch
12/28/2022, 1:23 PMeither { }
and option { }
builders are absolutely indispensable.CLOVIS
12/28/2022, 1:25 PMCLOVIS
12/28/2022, 1:26 PMeither {}
makes everything much, much easier to understandmitch
12/28/2022, 1:55 PMdata class Middleware<T>(val
`execute`: suspend ExecutionScope.() -> Either<ErrorResponse, T>)
So we'll have something like
class AuthorizationMiddlewares(...) {
fun authorizeToken(...): Middleware<Either<AuthzFailure, AuthorizedUser>> = middleware {
either {
// etc
}
}
}
mitch
12/28/2022, 1:58 PM