Skip to content

$code

$code is a standardized collection of HTTP status codes and application-specific error codes, providing a single source of truth for all status and error codes across your applications. Messages are automatically inferred when used with Result types.

Standardized status and error codes with auto-generated messages Comprehensive HTTP status codes plus custom application error codes with user-friendly messages automatically applied to Results.

Overview

The $code object provides:

  • Standard HTTP status codes (200, 404, 500, etc.)
  • Custom application error codes (4001, 4002, etc.)
  • Auto-inferred user messages - when you use ok() or err() with a $code value, the appropriate user message is automatically attached
  • TypeScript type safety with HTTPCode type
  • Consistent error handling across your application
  • Zero-configuration messaging - no need to write custom error messages

✅ Structure

ts
export const $code = {
  // 2xx Success
  ok: 200,
  created: 201,
  accepted: 202,
  noContent: 204,
  
  // 3xx Redirection  
  movedPermanently: 301,
  found: 302,
  notModified: 304,
  
  // 4xx Client Errors
  badRequest: 400,
  unauthorized: 401,
  forbidden: 403,
  notFound: 404,
  
  // Custom validation errors
  invalidEmailOrPassword: 4001,
  invalidEmail: 4002,
  weakPassword: 4003,
  validationTypeError: 4010,
  validationPatternError: 4011,
  // ... more validation codes
  
  // 5xx Server Errors
  unknown: 500,
  badGateway: 502,
  serviceUnavailable: 503,
  // ... more server codes
} as const

export type HTTPCode = (typeof $code)[keyof typeof $code]

📋 Code Categories

2xx Success Codes

CodeConstantDescription
200okStandard response for successful HTTP requests
201createdThe request has been fulfilled and a new resource created
202acceptedThe request has been accepted for processing
204noContentThe request succeeded but returns no content

3xx Redirection Codes

CodeConstantDescription
301movedPermanentlyThis and all future requests should be directed to the given URI
302foundThe requested resource resides temporarily under a different URI
304notModifiedThe resource has not been modified since last requested

4xx Client Error Codes

Standard HTTP Errors

CodeConstantDescription
400badRequestBad request syntax or invalid request
401unauthorizedAuthentication is required and has failed
403forbiddenThe client does not have access rights to the content
404notFoundThe server cannot find the requested resource
409conflictConflict in the request such as edit conflicts
429tooManyRequestsThe user has sent too many requests in a given amount of time

Custom Application Errors

CodeConstantDescription
4001invalidEmailOrPasswordInvalid email or password combination
4002invalidEmailEmail format is invalid
4003weakPasswordPassword doesn't meet security requirements
4041emailDoesntExistEmail not found in the database

Validation Error Codes

CodeConstantDescription
4010validationTypeErrorInvalid data type provided
4011validationPatternErrorInput doesn't match required pattern
4012validationRangeErrorValue is outside allowed range
4013validationLengthErrorInput length is invalid
4014validationRequiredErrorRequired field is missing
4015validationFormatErrorInput format is invalid

5xx Server Error Codes

CodeConstantDescription
500unknownThe server has encountered an unknown situation
501notImplementedThe request method is not supported by the server
502badGatewayThe server received an invalid response from upstream
503serviceUnavailableServer is currently unavailable

🗣️ User Messages

Each code has an associated user-friendly message:

ts
export const userErrorMessages = {
  200: "Request succeeded.",
  400: "Bad request. Please check your input.",
  4001: "Invalid email or password.",
  4002: "Please input a valid email.",
  404: "Resource not found.",
  500: "An unknown error occurred. Please try again later.",
  // ... complete mapping
} as const

🔄 Usage with Result Types

$code integrates seamlessly with the Result system, automatically inferring user messages:

ts
import { ok, err, $code } from "#appkit"

// Success responses with auto-inferred messages
const success = ok(userData, $code.ok)
// Result: { ok: true, data: userData, message: "Request succeeded." }

const created = ok(newUser, $code.created)  
// Result: { ok: true, data: newUser, message: "Resource created successfully." }

// Error responses with auto-inferred messages
const validation = err("Invalid email format", $code.invalidEmail)
// Result: { ok: false, error: "Invalid email format", message: "Please input a valid email." }

const notFound = err("User not found", $code.notFound)
// Result: { ok: false, error: "User not found", message: "Resource not found." }

const server = err("Database connection failed", $code.unknown)
// Result: { ok: false, error: "Database connection failed", message: "An unknown error occurred. Please try again later." }

// Enhanced debugging with expected/got context
const typeError = err("Wrong data type", $code.validationTypeError, {
  expected: { name: "string", age: "number" },
  got: { name: 123, age: "thirty" }
})
// Result includes: message: "Invalid data type provided." + debugging context

No manual message writing required! Every $code value has a corresponding user-friendly message that gets automatically attached to your Results.

🎯 Common Patterns

API Response Handling

ts
async function createUser(userData: any) {
  try {
    // Validate input
    if (!userData.email) {
      return err("Email is required", $code.validationRequiredError)
    }
    
    if (!isValidEmail(userData.email)) {
      return err("Invalid email format", $code.invalidEmail)
    }
    
    // Check if user exists
    const existing = await findUserByEmail(userData.email)
    if (existing) {
      return err("Email already registered", $code.emailAlreadyExists)
    }
    
    // Create user
    const user = await saveUser(userData)
    return ok(user, $code.created)
    
  } catch (error) {
    return err("Server error", $code.unknown)
  }
}

Form Validation

ts
function validateRegistrationForm(data: any) {
  const errors: string[] = []
  
  if (!data.email) {
    errors.push(userErrorMessages[$code.validationRequiredError])
  } else if (!isValidEmail(data.email)) {
    errors.push(userErrorMessages[$code.invalidEmail])
  }
  
  if (!data.password) {
    errors.push(userErrorMessages[$code.validationRequiredError])
  } else if (data.password.length < 8) {
    errors.push(userErrorMessages[$code.weakPassword])
  }
  
  return errors.length > 0 
    ? err(errors, $code.badRequest)
    : ok(data, $code.ok)
}

HTTP Response Mapping

ts
function mapResultToHttpResponse(result: Result<any, any>) {
  return $result(result).match({
    ok: (value) => ({
      status: value.code,
      body: {
        success: true,
        data: value.data,
        message: userErrorMessages[value.code]
      }
    }),
    err: (error) => ({
      status: error.code,
      body: {
        success: false,
        error: error.error,
        message: userErrorMessages[error.code]
      }
    })
  })
}

Client-Side Error Display

ts
// Vue component example
const form = $form("registration")

const handleSubmit = form.handleSubmit(async (result) => {
  if (!result.ok) {
    // Show validation errors
    form.errors.value = result.message
    return
  }
  
  try {
    const response = await createUser(result.data)
    
    $result(response).match({
      ok: (user) => {
        form.messages.value = [userErrorMessages[$code.created]]
        navigateTo('/dashboard')
      },
      err: (error) => {
        // Show appropriate error message based on code
        const message = userErrorMessages[error.code] || "An error occurred"
        form.errors.value = [message]
      }
    })
  } catch (error) {
    form.errors.value = [userErrorMessages[$code.unknown]]
  }
})

🔧 TypeScript Integration

ts
// Type-safe code usage
function handleApiError(code: HTTPCode): string {
  return userErrorMessages[code] // ✅ Type safe
}

// Custom error handling
function isClientError(code: HTTPCode): boolean {
  return code >= 400 && code < 500
}

function isValidationError(code: HTTPCode): boolean {
  return code >= 4010 && code < 4020
}

// Result creation with proper typing
function createTypedResult<T>(data: T, success: boolean): Result<T, string> {
  return success 
    ? ok(data, $code.ok)
    : err("Operation failed", $code.badRequest)
}

🌍 Internationalization

For multi-language applications, you can extend the message system:

ts
const messages = {
  en: userErrorMessages,
  es: {
    200: "Solicitud exitosa.",
    400: "Solicitud incorrecta. Verifique su entrada.",
    4001: "Email o contraseña inválidos.",
    // ... Spanish translations
  },
  fr: {
    200: "Demande réussie.",
    400: "Mauvaise demande. Veuillez vérifier votre saisie.",
    // ... French translations
  }
}

function getUserMessage(code: HTTPCode, locale: string = 'en'): string {
  return messages[locale]?.[code] || messages.en[code] || "Unknown error"
}

⚡ Best Practices

✅ Do

  • Use semantic constants instead of magic numbers: $code.notFound vs 404
  • Provide appropriate error codes for different failure scenarios
  • Use custom 4xxx codes for application-specific validation errors
  • Include user-friendly messages for client-facing errors
  • Map HTTP status codes consistently across your API

❌ Don't

  • Add new codes without documenting them
  • Change existing code values (this breaks compatibility)
  • Use generic error codes when specific ones exist
  • Expose internal error details to end users

🧠 Notes

  • Immutable: The $code object is const - values should never be changed
  • Extensible: You can add new codes, but never modify existing ones
  • Type-safe: Use the HTTPCode type for function parameters and return values
  • Consistent: User messages follow a consistent tone and format
  • Production-ready: Stack traces are omitted in production builds