DEV Community

Discussion on: I Stopped Using Try-Catch in TypeScript and You Should Too

Collapse
 
xwero profile image
david duymelinck

Lets take in account the "Problem with throwing" section, and rewrite the code.

class UserNotFound extends Error {
  constructor(message: string = 'User not found') {
    super(message);
    this.name = 'UserNotFound';
  }
}

class UserNotActive extends Error {
  constructor(message: string = 'User is not active') {
    super(message);
    this.name = 'UserNotActive';
  }
}

async function getUser(id: string): Promise<User | UserNotFound | UserNotActive> {
  const user = await db.query(`SELECT * FROM users WHERE id = ?`, [id]);
  if (!user) {
    return new UserNotFound();
  }
  if (!user.isActive) {
    return new UserNotActive();
  }
  return user;
}
Enter fullscreen mode Exit fullscreen mode
  1. The function signature is not lying to you anymore
  2. You know what output types to expect
  3. You are forced to check the output type
  4. The errors have context

The extra benefit is that the errors are checked on class name instead of on a string. This reduces errors by typos.

The main driver in the Result solution is that instead of throwing the errors they are returned. So you don't need the type to make the solution happen.