Skip to content

Communicate with middleware in pages via errors #242

Open

Description

Option 1: Error details

// page.astro
---
import type { APIContext } from "astro";
import type { AuthUser } from "../users";
import { login_path } from "./login_path";

const protected_route = <T extends AuthUser["role"] = "premium">(
  {
    locals: { auth },
    url,
    redirect,
  }: Pick<APIContext, "locals" | "url" | "redirect">,
  roles: Array<T> = ["premium"] as Array<T>
) => {
  if (!roles.includes(auth.user.role as T)) {
    throw Object.assign(redirect(login_path(url), 302), {
      __internal: true,
    });
  }
  return {
    user: auth.user as Extract<AuthUser, { role: T }>,
  };
};

const { user } = protected_route(Astro)
---
// middleware.ts
  try {
    return await next();
  } catch (e) {
    if (e instanceof Response && "__internal" in e && e.__internal === true) {
      return e;
    }
    // report error
}

Option 1 Discord message

Option2: Custom error class

export class ErrorWithResponse {
  constructor(message: string, private readonly builder: () => Response | Promise<Response>) {
    super(message);
  }
  
  render() {
    return this.builder();
  }
}

Option 2 Discord message

Example usecase:

Handle auth at page level

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions