Skip to content

Commit

Permalink
docs: updated 'Domain Errors' section
Browse files Browse the repository at this point in the history
  • Loading branch information
Sairyss committed Jul 20, 2022
1 parent b18f17b commit e357c2e
Showing 1 changed file with 13 additions and 3 deletions.
16 changes: 13 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -743,10 +743,10 @@ Exceptions are for exceptional situations. Complex domains usually have a lot of

Returning an error instead of throwing explicitly shows a type of each exception that a method can return so you can handle it accordingly. It can make an error handling and tracing easier.

To help with that you can create an [Algebraic Data Types (ADT)](https://en.wikipedia.org/wiki/Algebraic_data_type) for your errors and use some kind of Result object type with a Success or a Failure (an `Either` [monad](<https://en.wikipedia.org/wiki/Monad_(functional_programming)>) from functional languages like Haskell or Scala). Unlike throwing exceptions, this approach allows to define types (ADTs) for every error and will let you see and handle those cases explicitly instead of having invisible exceptions and using `try/catch`. For example:
To help with that you can create an [Algebraic Data Types (ADT)](https://en.wikipedia.org/wiki/Algebraic_data_type) for your errors and use some kind of Result object type with a Success or a Failure condition (a [monad](<https://en.wikipedia.org/wiki/Monad_(functional_programming)>) like [Either](https://typelevel.org/cats/datatypes/either.html) from functional languages similar to Haskell or Scala). Unlike throwing exceptions, this approach allows to define types (ADTs) for every error and will let you see and handle those cases explicitly instead of having invisible exceptions and using `try/catch`. For example:

```typescript
// ADTs for user errors:
// User errors:
class UserError extends Error {
/* ... */
}
Expand All @@ -755,17 +755,27 @@ class UserAlreadyExistsError extends UserError {
/* ... */
}

class IncorrectUserAddressError extends UserError {
/* ... */
}

// ... other user errors
```

```typescript
// Sum type for user errors
type CreateUserError = UserAlreadyExistsError | IncorrectUserAddressError;

function createUser(
command: CreateUserCommand,
): Result<UserEntity, UserAlreadyExistsError> {
): Result<UserEntity, CreateUserError> {
// ^ explicitly showing what function returns
if (await userRepo.exists(command.email)) {
return Err(new UserAlreadyExistsError()); // <- returning an Error
}
if (!validate(command.address)) {
return Err(new IncorrectUserAddressError());
}
// else
const user = await this.userRepo.create(user);
return Ok(user);
Expand Down

0 comments on commit e357c2e

Please sign in to comment.