Error Handling
Handling failures: error values vs exceptions
Introduction
In this lesson, you'll learn about error handling in TypeScript. Coming from Go, you already have a foundation for understanding this concept. We'll build on that knowledge while highlighting the key differences.
In Go, you're familiar with handling failures: error values vs exceptions.
TypeScript has its own approach to handling failures: error values vs exceptions, which we'll explore step by step.
The TypeScript Way
Let's see how TypeScript handles this concept. Here's a typical example:
class NotFoundError extends Error {
constructor(message: string) {
super(message);
this.name = "NotFoundError";
}
}
function findUser(id: number): User {
if (id <= 0) throw new Error("invalid id: " + id);
const user = db.get(id);
if (!user) throw new NotFoundError("user not found");
return user;
}
try {
const user = findUser(42);
console.log(user.name);
} catch (err) {
if (err instanceof NotFoundError) {
console.log("user not found");
} else {
console.log("error:", err);
}
}Comparing to Go
Here's how you might have written similar code in Go:
import "errors"
var ErrNotFound = errors.New("not found")
func findUser(id int) (*User, error) {
if id <= 0 {
return nil, fmt.Errorf("invalid id: %d", id)
}
user, ok := db[id]
if !ok {
return nil, ErrNotFound
}
return user, nil
}
user, err := findUser(42)
if err != nil {
if errors.Is(err, ErrNotFound) {
fmt.Println("user not found")
} else {
fmt.Println("error:", err)
}
return
}
fmt.Println(user.Name)You may be used to different syntax or behavior.
Go returns errors as values; TypeScript throws exceptions
You may be used to different syntax or behavior.
Go forces you to check errors at each call site; TypeScript can let them bubble up
You may be used to different syntax or behavior.
Go's errors.Is for comparison; TypeScript's instanceof for error types
You may be used to different syntax or behavior.
Go has no try/catch; TypeScript uses try/catch/finally
Step-by-Step Breakdown
1. Returning vs Throwing
Go functions return an error as the last value; TypeScript functions throw exceptions which unwind the call stack.
result, err := doSomething()
if err != nil { return err }try {
const result = doSomething(); // may throw
} catch (err) {
// handle it here
}2. Custom Error Types
Go creates sentinel errors with errors.New; TypeScript extends the Error class.
var ErrNotFound = errors.New("not found")class NotFoundError extends Error {
constructor(msg: string) { super(msg); this.name = "NotFoundError"; }
}3. Error Propagation
In Go you explicitly wrap and return errors up the call stack. In TypeScript, uncaught exceptions propagate automatically.
return fmt.Errorf("processUser: %w", err)// Rethrow with context:
throw new Error("processUser: " + err.message);Common Mistakes
When coming from Go, developers often make these mistakes:
- Go returns errors as values; TypeScript throws exceptions
- Go forces you to check errors at each call site; TypeScript can let them bubble up
- Go's errors.Is for comparison; TypeScript's instanceof for error types
Key Takeaways
- Go returns error values; TypeScript throws exceptions
- Go: if err != nil — TypeScript: try/catch
- Custom errors: Go sentinel errors → TypeScript extends Error
- TypeScript errors bubble up automatically; Go requires explicit propagation