Skip to content

Instantly share code, notes, and snippets.

@myuwono
myuwono / ContextReceiversPetService.kt
Created April 16, 2023 13:08
typed-error handling Arrow raise with context receivers
context(Raise<UpdatePetDetailsFailure>)
suspend fun updatePetDetails(
petId: PetId,
petOwnerId: PetOwnerId,
petUpdate: PetUpdate
): Pet {
val pet = petStore.getPet(petId) ?: raise(UpdatePetDetailsFailure.PetNotFound)
val owner = petOwnerStore.getPetOwner(petOwnerId) ?: raise(UpdatePetDetailsFailure.OwnerNotFound)
val microchip = microchipStore.getMicrochip(pet.microchipId) ?: raise(UpdatePetDetailsFailure.MicrochipNotFound)
@myuwono
myuwono / ArrowEitherBuilderPetService.kt
Created April 16, 2023 12:45
typed-error handling - Arrow either { } builder
suspend fun updatePetDetails(
petId: PetId,
petOwnerId: PetOwnerId,
petUpdate: PetUpdate
): Either<UpdatePetDetailsFailure, Pet> = either {
val pet = petStore.getPet(petId) ?: raise(UpdatePetDetailsFailure.PetNotFound)
val owner = petOwnerStore.getPetOwner(petOwnerId) ?: raise(UpdatePetDetailsFailure.OwnerNotFound)
val microchip = microchipStore.getMicrochip(pet.microchipId) ?: raise(UpdatePetDetailsFailure.MicrochipNotFound)
ensure(microchip.petId == pet.id) { UpdatePetDetailsFailure.InvalidMicrochip }
@myuwono
myuwono / SealedClassEarlyReturnPetService.kt
Last active April 16, 2023 12:28
typed-error handling sealed class early return
suspend fun updatePetDetails(
petId: PetId,
petOwnerId: PetOwnerId,
petUpdate: PetUpdate
): UpdatePetDetailsResult {
val pet = petStore.getPet(petId) ?: return UpdatePetDetailsResult.PetNotFound
val owner = petOwnerStore.getPetOwner(petOwnerId) ?: return UpdatePetDetailsResult.OwnerNotFound
val microchip = microchipStore.getMicrochip(pet.microchipId) ?: return UpdatePetDetailsResult.MicrochipNotFound
if (microchip.petId != pet.id) {
@myuwono
myuwono / ExceptionPetService.kt
Created April 16, 2023 11:33
typed-error handling Exceptions
suspend fun updatePetDetails(
petId: PetId,
petOwnerId: PetOwnerId,
petUpdate: PetUpdate
): Pet = try {
val pet = petStore.getPet(petId)
val owner = petOwnerStore.getPetOwner(petOwnerId)
val microchip = microchipStore.getMicrochip(pet.microchipId)
if (microchip.petId != pet.id) {
@myuwono
myuwono / EitherFlatMapPetService.kt
Created April 16, 2023 11:16
typed-error handling - vanilla Either FlatMap chaining
suspend fun updatePetDetails(
petId: PetId,
petOwnerId: PetOwnerId,
petUpdate: PetUpdate
): Either<UpdatePetDetailsFailure, Pet> =
petStore.getPet(petId)
.toEither { UpdatePetDetailsFailure.PetNotFound }
.flatMap { pet ->
petOwnerStore.getPetOwner(petOwnerId)
.toEither { UpdatePetDetailsFailure.OwnerNotFound }
@myuwono
myuwono / SealedClassPetService.kt
Last active April 16, 2023 10:45
typed-error-handling example - vanilla sealed class without early return
suspend fun updatePetDetails(
petId: PetId,
petOwnerId: PetOwnerId,
petUpdate: PetUpdate
): UpdatePetDetailsResult {
val pet = petStore.getPet(petId)
return if (pet == null) {
UpdatePetDetailsResult.PetNotFound
} else {
val owner = petOwnerStore.getPetOwner(petOwnerId)
@myuwono
myuwono / ContextReceiversPetService.kt
Created April 16, 2023 10:21
Kotlin typed-error handling - Error handling with vanilla sealed class without early returns
context(Raise<UpdatePetDetailsFailure>)
suspend fun updatePetDetails(
petId: PetId,
petOwnerId: PetOwnerId,
petUpdate: PetUpdate
): Pet {
val pet = petStore.getPet(petId) ?: raise(UpdatePetDetailsFailure.PetNotFound)
val owner = petOwnerStore.getPetOwner(petOwnerId) ?: raise(UpdatePetDetailsFailure.OwnerNotFound)
val microchip = microchipStore.getMicrochip(pet.microchipId) ?: raise(UpdatePetDetailsFailure.MicrochipNotFound)