Skip to content

Commit eb97582

Browse files
committed
fix(target server): handle malformed json properly
1 parent 3b1115d commit eb97582

File tree

16 files changed

+106
-41
lines changed

16 files changed

+106
-41
lines changed

dist/esm/error/funcs.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
import type { ErrorMessage, HTTPStatusNumber } from '../dt/index.js';
2+
export declare function isEmptyJSON(err: unknown): boolean;
3+
export declare function isInvalidJSON(err: unknown): boolean;
24
export declare function throwCustomError(message: ErrorMessage, status: HTTPStatusNumber): never;

dist/esm/error/funcs.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,26 @@ const ERROR_HTTP_STATUS_MAP = new Map([
1010
[404, NotFoundError],
1111
[500, InternalServerError],
1212
]);
13+
export function isEmptyJSON(err) {
14+
return (err instanceof Error &&
15+
err.message.toLowerCase().includes('unexpected end of json input'));
16+
}
17+
export function isInvalidJSON(err) {
18+
if (!(err instanceof Error)) {
19+
return false;
20+
}
21+
const message = err.message.toLowerCase();
22+
// The usual JS error thrown by JSON.parse
23+
if (message.includes('is not valid json')) {
24+
return true;
25+
}
26+
// The error thrown by undici (used by hono for example)
27+
// https://github.com/nodejs/undici/blob/ec4a84e13a9b86355b4d65a63a247524986386af/lib/web/fetch/body.js#L402
28+
if (message.includes('content-type was not one of')) {
29+
return true;
30+
}
31+
return false;
32+
}
1333
export function throwCustomError(message, status) {
1434
const clazz = ERROR_HTTP_STATUS_MAP.get(status);
1535
if (clazz) {

dist/esm/error/index.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
export { CustomError, type ServerError } from './CustomError.js';
22
export { ForbiddenAsNotFoundError } from './ForbiddenAsNotFoundError.js';
33
export { ForbiddenError } from './ForbiddenError.js';
4-
export { throwCustomError } from './funcs.js';
4+
export { isEmptyJSON, isInvalidJSON, throwCustomError } from './funcs.js';
55
export { IllegalArgumentError } from './IllegalArgumentError.js';
66
export { InternalServerError } from './InternalServerError.js';
77
export { NotAvailableError } from './internal/NotAvailableError.js';

dist/esm/error/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
export { CustomError } from './CustomError.js';
22
export { ForbiddenAsNotFoundError } from './ForbiddenAsNotFoundError.js';
33
export { ForbiddenError } from './ForbiddenError.js';
4-
export { throwCustomError } from './funcs.js';
4+
export { isEmptyJSON, isInvalidJSON, throwCustomError } from './funcs.js';
55
export { IllegalArgumentError } from './IllegalArgumentError.js';
66
export { InternalServerError } from './InternalServerError.js';
77
export { NotAvailableError } from './internal/NotAvailableError.js';

dist/esm/target/edge-worker-hono-server/SyncEdgeWorkerHonoServerManager.d.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,21 @@ import type { AppManifest } from '../../app/index.js';
33
import type { DirPath } from '../../dt/index.js';
44
import type { Configurable, SettingsManager } from '../../std/index.js';
55
import type { UCDataStore, UCDef, UCHTTPContract, UCInput, UCManager, UCOPIBase } from '../../uc/index.js';
6+
import { CustomerFacingErrorBuilder } from '../lib/server/CustomerFacingErrorBuilder.js';
67
import type { ServerManager } from '../lib/server/ServerManager.js';
78
import { ServerRequestHandler } from '../lib/server/ServerRequestHandler.js';
89
export interface SyncEdgeWorkerHonoServerManagerSettings {
910
sewhsm_bindings_uc_data_store: string | null;
1011
}
1112
type S = SyncEdgeWorkerHonoServerManagerSettings;
1213
export declare class SyncEdgeWorkerHonoServerManager implements Configurable<S>, ServerManager {
14+
private customerFacingErrorBuilder;
1315
private serverRequestHandler;
1416
private settingsManager;
1517
private ucDataStore;
1618
private ucManager;
1719
protected runtime: Hono;
18-
constructor(serverRequestHandler: ServerRequestHandler, settingsManager: SettingsManager<S>, ucDataStore: UCDataStore, ucManager: UCManager);
20+
constructor(customerFacingErrorBuilder: CustomerFacingErrorBuilder, serverRequestHandler: ServerRequestHandler, settingsManager: SettingsManager<S>, ucDataStore: UCDataStore, ucManager: UCManager);
1921
s(): SyncEdgeWorkerHonoServerManagerSettings;
2022
getRuntime(): Hono;
2123
overrideUCManager(ucManager: UCManager): void;

dist/esm/target/edge-worker-hono-server/SyncEdgeWorkerHonoServerManager.js

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,18 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
1212
};
1313
import { inject, injectable } from 'inversify';
1414
import { NotAvailableError, NotCallableError } from '../../error/index.js';
15+
import { CustomerFacingErrorBuilder } from '../lib/server/CustomerFacingErrorBuilder.js';
1516
import { ServerRequestHandler } from '../lib/server/ServerRequestHandler.js';
1617
import { buildHandler, init, mountHandler } from '../lib/server-hono/funcs.js';
1718
let SyncEdgeWorkerHonoServerManager = class SyncEdgeWorkerHonoServerManager {
19+
customerFacingErrorBuilder;
1820
serverRequestHandler;
1921
settingsManager;
2022
ucDataStore;
2123
ucManager;
2224
runtime;
23-
constructor(serverRequestHandler, settingsManager, ucDataStore, ucManager) {
25+
constructor(customerFacingErrorBuilder, serverRequestHandler, settingsManager, ucDataStore, ucManager) {
26+
this.customerFacingErrorBuilder = customerFacingErrorBuilder;
2427
this.serverRequestHandler = serverRequestHandler;
2528
this.settingsManager = settingsManager;
2629
this.ucDataStore = ucDataStore;
@@ -41,7 +44,7 @@ let SyncEdgeWorkerHonoServerManager = class SyncEdgeWorkerHonoServerManager {
4144
throw new NotCallableError('init', 'initSync', 'sync-only');
4245
}
4346
initSync() {
44-
this.runtime = init();
47+
this.runtime = init(this.customerFacingErrorBuilder);
4548
}
4649
async mount(_appManifest, _ucd, _contract) {
4750
throw new NotCallableError('mount', 'mountSync', 'sync-only');
@@ -78,10 +81,12 @@ let SyncEdgeWorkerHonoServerManager = class SyncEdgeWorkerHonoServerManager {
7881
};
7982
SyncEdgeWorkerHonoServerManager = __decorate([
8083
injectable(),
81-
__param(0, inject(ServerRequestHandler)),
82-
__param(1, inject('SettingsManager')),
83-
__param(2, inject('UCDataStore')),
84-
__param(3, inject('UCManager')),
85-
__metadata("design:paramtypes", [ServerRequestHandler, Object, Object, Object])
84+
__param(0, inject(CustomerFacingErrorBuilder)),
85+
__param(1, inject(ServerRequestHandler)),
86+
__param(2, inject('SettingsManager')),
87+
__param(3, inject('UCDataStore')),
88+
__param(4, inject('UCManager')),
89+
__metadata("design:paramtypes", [CustomerFacingErrorBuilder,
90+
ServerRequestHandler, Object, Object, Object])
8691
], SyncEdgeWorkerHonoServerManager);
8792
export { SyncEdgeWorkerHonoServerManager };

dist/esm/target/lib/server-express/funcs.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@ import type { AppManifest } from '../../../app/index.js';
44
import type { File } from '../../../dt/index.js';
55
import type { LoggerLevel } from '../../../std/index.js';
66
import type { UCDef, UCHTTPContract, UCInput, UCManager, UCOPIBase } from '../../../uc/index.js';
7+
import type { CustomerFacingErrorBuilder } from '../server/CustomerFacingErrorBuilder.js';
78
import type { ServerManagerSettings } from '../server/ServerManager.js';
89
import type { ServerRequestHandler, ServerRequestHandlerReq, ServerRequestHandlerRes } from '../server/ServerRequestHandler.js';
910
import type { HelmetMiddlewareBuilder } from './HelmetMiddlewareBuilder.js';
1011
export declare function buildHandler<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(appManifest: AppManifest, ucd: UCDef<I, OPI0, OPI1>, contract: UCHTTPContract, serverRequestHandler: ServerRequestHandler, ucManager: UCManager): RequestHandler;
1112
export declare function init(helmetMB: HelmetMiddlewareBuilder, loggerLevel: LoggerLevel, serverTmpPath: ServerManagerSettings['server_tmp_path']): Express;
1213
export declare function mountHandler(contract: UCHTTPContract, express: Express, handler: RequestHandler): void;
14+
export declare function postInit(app: Express, customerFacingErrorBuilder: CustomerFacingErrorBuilder): void;
1315
export declare function toFile(f: fileUpload.UploadedFile): File;
1416
export declare function toReq(req: Request): ServerRequestHandlerReq;
1517
export declare function toRes(res: Response): ServerRequestHandlerRes;

dist/esm/target/lib/server-express/funcs.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,12 @@ export function mountHandler(contract, express, handler) {
9494
express[httpMethod](pathAlias, handler);
9595
}
9696
}
97+
export function postInit(app, customerFacingErrorBuilder) {
98+
app.use((err, _req, res, _next) => {
99+
const { error } = customerFacingErrorBuilder.exec({ error: err });
100+
return res.status(error.httpStatus).json(error.toObj());
101+
});
102+
}
97103
export function toFile(f) {
98104
return {
99105
name: f.name,

dist/esm/target/lib/server-hono/funcs.d.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ import { type Context, type Handler, Hono } from 'hono';
22
import type { BlankEnv, Env } from 'hono/types';
33
import type { AppManifest } from '../../../app/index.js';
44
import type { UCDef, UCHTTPContract, UCInput, UCManager, UCOPIBase } from '../../../uc/index.js';
5+
import type { CustomerFacingErrorBuilder } from '../server/CustomerFacingErrorBuilder.js';
56
import type { ServerRequestHandler, ServerRequestHandlerReq, ServerRequestHandlerRes } from '../server/ServerRequestHandler.js';
67
export declare function buildHandler<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(appManifest: AppManifest, ucd: UCDef<I, OPI0, OPI1>, contract: UCHTTPContract, serverRequestHandler: ServerRequestHandler, ucManager: UCManager, beforeExec?: (c: Context) => Promise<void>): Handler;
7-
export declare function init<E extends Env = BlankEnv>(): Hono<E>;
8+
export declare function init<E extends Env = BlankEnv>(customerFacingErrorBuilder: CustomerFacingErrorBuilder): Hono<E>;
89
export declare function mountHandler(contract: UCHTTPContract, hono: Hono, handler: Handler): void;
910
export declare function toReq(c: Context): ServerRequestHandlerReq;
1011
export declare function toRes(c: Context): ServerRequestHandlerRes;

dist/esm/target/lib/server-hono/funcs.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,17 @@ export function buildHandler(appManifest, ucd, contract, serverRequestHandler, u
8686
};
8787
return handler;
8888
}
89-
export function init() {
89+
export function init(customerFacingErrorBuilder) {
9090
const app = new Hono();
9191
app.use(secureHeaders());
9292
app.use(logger());
9393
app.notFound((c) => {
94-
const err = new NotFoundError();
95-
return c.json(err.toObj(), err.httpStatus);
94+
const error = new NotFoundError();
95+
return c.json(error.toObj(), error.httpStatus);
96+
});
97+
app.onError((err, c) => {
98+
const { error } = customerFacingErrorBuilder.exec({ error: err });
99+
return c.json(error.toObj(), error.httpStatus);
96100
});
97101
return app;
98102
}

0 commit comments

Comments
 (0)