Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/playground-preview-worker/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
root: true,
extends: ["@cloudflare/eslint-config-worker"],
};
4 changes: 3 additions & 1 deletion packages/playground-preview-worker/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,18 @@
"build-middleware": "pnpm run build-middleware:common && pnpm run build-middleware:loader",
"build-middleware:common": "pnpm dlx esbuild ../wrangler/templates/middleware/common.ts --outfile=src/middleware/common.module.template",
"build-middleware:loader": "pnpm dlx esbuild ../wrangler/templates/middleware/loader-modules.ts --outfile=src/middleware/loader.module.template",
"check:lint": "eslint .",
"deploy": "wrangler -j deploy",
"deploy:testing": "wrangler -j deploy -e testing",
"start": "wrangler -j dev",
"test:e2e": "vitest run"
},
"dependencies": {
"hono": "^3.3.2",
"hono": "^3.12.11",
"zod": "^3.22.3"
},
"devDependencies": {
"@cloudflare/eslint-config-worker": "workspace:*",
"@cloudflare/workers-types": "^4.20230321.0",
"@types/cookie": "^0.5.1",
"cookie": "^0.5.0",
Expand Down
124 changes: 124 additions & 0 deletions packages/playground-preview-worker/src/errors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import type { ZodIssue } from "zod";

export class HttpError extends Error {
constructor(
message: string,
readonly status: number,
// Only report errors to sentry when they represent actionable errors
readonly reportable: boolean
) {
super(message);
Object.setPrototypeOf(this, new.target.prototype);
}
toResponse() {
return Response.json(
{
error: this.name,
message: this.message,
data: this.data,
},
{
status: this.status,
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET,PUT,POST",
},
}
);
}

get data(): Record<string, unknown> {
return {};
}
}

export class WorkerTimeout extends HttpError {
name = "WorkerTimeout";
constructor() {
super("Worker timed out", 400, false);
}

toResponse(): Response {
return new Response("Worker timed out");
}
}

export class ServiceWorkerNotSupported extends HttpError {
name = "ServiceWorkerNotSupported";
constructor() {
super(
"Service Workers are not supported in the Workers Playground",
400,
false
);
}
}
export class ZodSchemaError extends HttpError {
name = "ZodSchemaError";
constructor(private issues: ZodIssue[]) {
super("Something went wrong", 500, true);
}

get data(): { issues: string } {
return { issues: JSON.stringify(this.issues) };
}
}

export class PreviewError extends HttpError {
name = "PreviewError";
constructor(private error: string) {
super(error, 400, false);
}

get data(): { error: string } {
return { error: this.error };
}
}

export class TokenUpdateFailed extends HttpError {
name = "TokenUpdateFailed";
constructor() {
super("Provide valid token", 400, false);
}
}

export class RawHttpFailed extends HttpError {
name = "RawHttpFailed";
constructor() {
super("Provide valid token", 400, false);
}
}

export class PreviewRequestFailed extends HttpError {
name = "PreviewRequestFailed";
constructor(private tokenId: string | undefined, reportable: boolean) {
super("Valid token not found", 400, reportable);
}
get data(): { tokenId: string | undefined } {
return { tokenId: this.tokenId };
}
}

export class UploadFailed extends HttpError {
name = "UploadFailed";
constructor() {
super("Valid token not provided", 401, false);
}
}

export class PreviewRequestForbidden extends HttpError {
name = "PreviewRequestForbidden";
constructor() {
super("Preview request forbidden", 403, false);
}
}

export class BadUpload extends HttpError {
name = "BadUpload";
constructor(message = "Invalid upload", private readonly error?: string) {
super(message, 400, false);
}
get data() {
return { error: this.error };
}
}
127 changes: 11 additions & 116 deletions packages/playground-preview-worker/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
import { Hono } from "hono";
import { getCookie, setCookie } from "hono/cookie";
import prom from "promjs";
import { Toucan } from "toucan-js";
import { ZodIssue } from "zod";
import {
HttpError,
PreviewRequestFailed,
PreviewRequestForbidden,
RawHttpFailed,
TokenUpdateFailed,
UploadFailed,
} from "./errors";
import { handleException, setupSentry } from "./sentry";
import type { RegistryType } from "promjs";
import type { Toucan } from "toucan-js";

const app = new Hono<{
Bindings: Env;
Expand All @@ -20,118 +27,6 @@ const app = new Hono<{

const rootDomain = ROOT;
const previewDomain = PREVIEW;
export class HttpError extends Error {
constructor(
message: string,
readonly status: number,
// Only report errors to sentry when they represent actionable errors
readonly reportable: boolean
) {
super(message);
Object.setPrototypeOf(this, new.target.prototype);
}
toResponse() {
return Response.json(
{
error: this.name,
message: this.message,
data: this.data,
},
{
status: this.status,
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET,PUT,POST",
},
}
);
}

get data(): Record<string, unknown> {
return {};
}
}

export class WorkerTimeout extends HttpError {
name = "WorkerTimeout";
constructor() {
super("Worker timed out", 400, false);
}

toResponse(): Response {
return new Response("Worker timed out");
}
}

export class ServiceWorkerNotSupported extends HttpError {
name = "ServiceWorkerNotSupported";
constructor() {
super(
"Service Workers are not supported in the Workers Playground",
400,
false
);
}
}
export class ZodSchemaError extends HttpError {
name = "ZodSchemaError";
constructor(private issues: ZodIssue[]) {
super("Something went wrong", 500, true);
}

get data(): { issues: string } {
return { issues: JSON.stringify(this.issues) };
}
}

export class PreviewError extends HttpError {
name = "PreviewError";
constructor(private error: string) {
super(error, 400, false);
}

get data(): { error: string } {
return { error: this.error };
}
}

class TokenUpdateFailed extends HttpError {
name = "TokenUpdateFailed";
constructor() {
super("Provide valid token", 400, false);
}
}

class RawHttpFailed extends HttpError {
name = "RawHttpFailed";
constructor() {
super("Provide valid token", 400, false);
}
}

class PreviewRequestFailed extends HttpError {
name = "PreviewRequestFailed";
constructor(private tokenId: string | undefined, reportable: boolean) {
super("Valid token not found", 400, reportable);
}
get data(): { tokenId: string | undefined } {
return { tokenId: this.tokenId };
}
}

class UploadFailed extends HttpError {
name = "UploadFailed";
constructor() {
super("Valid token not provided", 401, false);
}
}

class PreviewRequestForbidden extends HttpError {
name = "PreviewRequestForbidden";
constructor() {
super("Preview request forbidden", 403, false);
}
}

/**
* Given a preview token, this endpoint allows for raw http calls to be inspected
Expand Down Expand Up @@ -254,7 +149,7 @@ app.get(`${rootDomain}/`, async (c) => {
});

app.post(`${rootDomain}/api/worker`, async (c) => {
let userId = getCookie(c, "user");
const userId = getCookie(c, "user");
if (!userId) {
throw new UploadFailed();
}
Expand All @@ -275,7 +170,7 @@ app.post(`${rootDomain}/api/worker`, async (c) => {

app.get(`${rootDomain}/api/inspector`, async (c) => {
const url = new URL(c.req.url);
let userId = url.searchParams.get("user");
const userId = url.searchParams.get("user");
if (!userId) {
throw new PreviewRequestFailed("", false);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/playground-preview-worker/src/realish.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { z } from "zod";
import { PreviewError } from ".";
import { PreviewError } from "./errors";

const APIResponse = <T extends z.ZodTypeAny>(resultSchema: T) =>
z.union([
Expand Down
4 changes: 2 additions & 2 deletions packages/playground-preview-worker/src/sentry.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Toucan } from "toucan-js";
import { z, ZodError } from "zod";
import { HttpError, ZodSchemaError } from ".";
import { ZodError } from "zod";
import { HttpError, ZodSchemaError } from "./errors";

export function handleException(e: unknown, sentry: Toucan): Response {
console.error(e);
Expand Down
Loading