Example 2

interface User {
    name: string
    surname?: string
    age: number
}

const users: User[] = [{
    name: "alice",
    surname: "zuberg",
    age: 19
}, {
    name: "asuna",
    surname: "yuuki",
    age: 19
}, {
    name: "kazuto",
    surname: "Kirigaya",
    age: 17
}]
import { ProjectError, wrap } from '@sirutils/core'

const getUser = wrap((name: User["name"]) => {
    const found = users.find(user => user.name === name)

    if(!found) {
        return ProjectError.create("?not-found", "user not found").throw()
    }

    return found
}, "?get-user")

const addUser = wrap((user: User) => {
    const exists = getUser(user.name) 

    if(exists.isOk()) {
        return ProjectError.create("exists", `user: ${user.name} already exists`).throw()
    }

    users.push(user)

    return true
}, "?add-user")

const result = addUser({
    name: "yui",
    age: 2
})

if(result.isErr()) {
    console.log(result.error)
    process.exit()
}

console.log(result.value)

This code snippet demonstrates the use of error handling in JavaScript, utilizing a utility function wrap from the @sirutils/core library, and a custom ProjectError class for managing errors. Here’s a step-by-step explanation:

1. Import Statements:

import { ProjectError, wrap } from '@sirutils/core'
  • ProjectError: A custom error class that likely has methods for creating and throwing errors.
  • wrap: A utility function that wraps other functions, enabling additional functionality such as automatic error handling or logging.

2. The getUser Function:

const getUser = wrap((name: User["name"]) => {
    const found = users.find(user => user.name === name)

    if(!found) {
        return ProjectError.create("?not-found", "user not found").throw()
    }

    return found
}, "?get-user")
  • Purpose: This function searches for a user by their name in the users array.
  • Logic: -It attempts to find the user by their name.
    • If the user is not found, it creates and throws a ProjectError with the message "user not found" and an error code "?not-found".
    • If the user is found, it returns the user object.
  • wrap: The function is wrapped with wrap, which likely enhances it by automatically managing the function’s return values, possibly converting thrown errors into structured results.

3. The addUser Function:

const addUser = wrap((user: User) => {
    const exists = getUser(user.name) 

    if(exists.isOk()) {
        return ProjectError.create("exists", `user: ${user.name} already exists`).throw()
    }

    users.push(user)

    return true
}, "?add-user")
  • Purpose: This function attempts to add a new user to the users array.
  • Logic:
    • It first checks if a user with the same name already exists using the getUser function.
    • If the user exists (i.e., getUser returned a successful result), it creates and throws a ProjectError with the message "user already exists" and an error code "exists".
    • If the user doesn’t exist, it adds the new user to the users array and returns true.
  • wrap: Like getUser, addUser is also wrapped, which likely ensures that errors are managed and the function consistently returns a structured result.

4. Executing addUser and Handling the Result:

const result = addUser({
    name: "yui",
    age: 2
})

if(result.isErr()) {
    console.log(result.error)

    process.exit()
}

console.log(result.value)
  • Adding a User: The addUser function is called with a user object { name: "yui", age: 2 }.
  • Error Handling:
    • If addUser returns an error result (result.isErr()), it logs the error and exits the process.
    • If no error occurs, it logs the result.value, which would be true in this case if the user was successfully added.

Summary:

  • The code is designed to safely manage adding and retrieving users from a list.
  • wrap ensures consistent error handling and result management.
  • ProjectError provides a structured way to create, throw, and handle errors.
  • The code flow is designed to stop execution if errors occur, preventing further processing of invalid states.