@b9g/http-errors 0.1.4 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@b9g/http-errors",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "Standard HTTP error responses for ServiceWorker applications. Returns proper Response objects with status codes, not thrown exceptions.",
5
5
  "keywords": [
6
6
  "http",
package/src/index.d.ts CHANGED
@@ -35,6 +35,12 @@ export declare class HTTPError extends Error {
35
35
  expose: boolean;
36
36
  headers: Record<string, string>;
37
37
  };
38
+ /**
39
+ * Convert error to an HTTP Response
40
+ * In development mode, shows detailed error page with stack trace
41
+ * In production mode, shows minimal error message
42
+ */
43
+ toResponse(isDev?: boolean): Response;
38
44
  }
39
45
  /**
40
46
  * Special error for middleware fallthrough (not an HTTP error)
package/src/index.js CHANGED
@@ -71,7 +71,51 @@ var HTTPError = class extends Error {
71
71
  headers: this.headers
72
72
  };
73
73
  }
74
+ /**
75
+ * Convert error to an HTTP Response
76
+ * In development mode, shows detailed error page with stack trace
77
+ * In production mode, shows minimal error message
78
+ */
79
+ toResponse(isDev) {
80
+ const headers = new Headers(this.headers);
81
+ if (isDev && this.expose) {
82
+ headers.set("Content-Type", "text/html; charset=utf-8");
83
+ const statusText = STATUS_CODES[this.status] || "Error";
84
+ const html = `<!DOCTYPE html>
85
+ <html>
86
+ <head>
87
+ <title>${this.status} ${escapeHTML(statusText)}</title>
88
+ <style>
89
+ body { font-family: system-ui, sans-serif; padding: 2rem; max-width: 800px; margin: 0 auto; }
90
+ h1 { color: ${this.status >= 500 ? "#c00" : "#e67700"}; }
91
+ .message { font-size: 1.2em; color: #333; }
92
+ pre { background: #f5f5f5; padding: 1rem; overflow-x: auto; border-radius: 4px; }
93
+ </style>
94
+ </head>
95
+ <body>
96
+ <h1>${this.status} ${escapeHTML(statusText)}</h1>
97
+ <p class="message">${escapeHTML(this.message)}</p>
98
+ <pre>${escapeHTML(this.stack || "No stack trace available")}</pre>
99
+ </body>
100
+ </html>`;
101
+ return new Response(html, {
102
+ status: this.status,
103
+ statusText,
104
+ headers
105
+ });
106
+ }
107
+ headers.set("Content-Type", "text/plain; charset=utf-8");
108
+ const body = this.expose ? this.message : STATUS_CODES[this.status] || "Error";
109
+ return new Response(body, {
110
+ status: this.status,
111
+ statusText: STATUS_CODES[this.status],
112
+ headers
113
+ });
114
+ }
74
115
  };
116
+ function escapeHTML(str) {
117
+ return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
118
+ }
75
119
  var NotHandled = class extends Error {
76
120
  constructor(message = "Request not handled by middleware") {
77
121
  super(message);