mirror of
https://github.com/samuelthomas2774/nxapi.git
synced 2026-03-21 18:04:10 -05:00
HTTP server errors
This commit is contained in:
parent
ed63648ddf
commit
30333dec8e
|
|
@ -755,10 +755,7 @@ class Server extends HttpServer {
|
|||
this.resetAuthTimeout(na_session_token, () => user.data.user.id);
|
||||
}
|
||||
} catch (err) {
|
||||
stream.sendEvent('error', {
|
||||
error: (err as Error).name,
|
||||
error_message: (err as Error).message,
|
||||
});
|
||||
stream.sendErrorEvent(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1095,8 +1095,9 @@ class Server extends HttpServer {
|
|||
|
||||
if (retry_after && /^\d+$/.test(retry_after)) {
|
||||
stream.sendEvent(null, 'debug: timestamp ' + new Date().toISOString(), {
|
||||
error: err,
|
||||
error: 'unknown_error',
|
||||
error_message: (err as Error).message,
|
||||
...err,
|
||||
});
|
||||
|
||||
await new Promise(rs => setTimeout(rs, parseInt(retry_after) * 1000));
|
||||
|
|
@ -1105,17 +1106,7 @@ class Server extends HttpServer {
|
|||
}
|
||||
}
|
||||
|
||||
if (err instanceof ResponseError) {
|
||||
stream.sendEvent('error', {
|
||||
error: err.code,
|
||||
error_message: err.message,
|
||||
});
|
||||
} else {
|
||||
stream.sendEvent('error', {
|
||||
error: err,
|
||||
error_message: (err as Error).message,
|
||||
});
|
||||
}
|
||||
stream.sendErrorEvent(err);
|
||||
|
||||
debug('Error in event stream %d', stream.id, err);
|
||||
|
||||
|
|
|
|||
|
|
@ -71,10 +71,7 @@ export class HttpServer {
|
|||
if (err instanceof ResponseError) {
|
||||
err.sendResponse(req, res);
|
||||
} else {
|
||||
this.sendJsonResponse(res, {
|
||||
error: err,
|
||||
error_message: (err as Error).message,
|
||||
}, 500);
|
||||
this.sendJsonResponse(res, getErrorObject(err), 500);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -85,16 +82,24 @@ export class ResponseError extends Error {
|
|||
}
|
||||
|
||||
sendResponse(req: Request, res: Response) {
|
||||
const data = {
|
||||
error: this.code,
|
||||
error_message: this.message,
|
||||
};
|
||||
const data = this.toJSON();
|
||||
|
||||
res.statusCode = this.status;
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
res.end(req.headers['accept']?.match(/\/html\b/i) ?
|
||||
JSON.stringify(data, null, 4) : JSON.stringify(data));
|
||||
}
|
||||
|
||||
sendEventStreamEvent(events: EventStreamResponse) {
|
||||
events.sendEvent('error', this.toJSON());
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
return {
|
||||
error: this.code,
|
||||
error_message: this.message,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export class EventStreamResponse {
|
||||
|
|
@ -123,8 +128,96 @@ export class EventStreamResponse {
|
|||
|
||||
sendEvent(event: string | null, ...data: unknown[]) {
|
||||
if (event) this.res.write('event: ' + event + '\n');
|
||||
for (const d of data) this.res.write('data: ' + JSON.stringify(d,
|
||||
this.json_replacer ? (k, v) => this.json_replacer?.call(null, k, v, d) : undefined) + '\n');
|
||||
for (const d of data) {
|
||||
if (d instanceof EventStreamField) d.write(this.res);
|
||||
else this.res.write('data: ' + JSON.stringify(d,
|
||||
this.json_replacer ? (k, v) => this.json_replacer?.call(null, k, v, d) : undefined) + '\n');
|
||||
}
|
||||
this.res.write('\n');
|
||||
}
|
||||
|
||||
sendErrorEvent(err: unknown) {
|
||||
if (err instanceof ResponseError) {
|
||||
err.sendEventStreamEvent(this);
|
||||
} else {
|
||||
this.sendEvent('error', getErrorObject(err));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract class EventStreamField {
|
||||
abstract write(res: Response): void;
|
||||
}
|
||||
|
||||
export class EventStreamLastEventId extends EventStreamField {
|
||||
constructor(
|
||||
readonly id: string,
|
||||
) {
|
||||
super();
|
||||
|
||||
if (!/^[0-9a-z-_\.:;]+$/i.test(id)) {
|
||||
throw new TypeError('Invalid event ID');
|
||||
}
|
||||
}
|
||||
|
||||
write(res: Response) {
|
||||
res.write('id: ' + this.id + '\n');
|
||||
}
|
||||
}
|
||||
|
||||
export class EventStreamRetryTime extends EventStreamField {
|
||||
constructor(
|
||||
readonly retry_ms: number,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
write(res: Response) {
|
||||
res.write('retry: ' + this.retry_ms + '\n');
|
||||
}
|
||||
}
|
||||
|
||||
export class EventStreamRawData extends EventStreamField {
|
||||
constructor(
|
||||
readonly data: string,
|
||||
) {
|
||||
super();
|
||||
|
||||
if (/[\0\n\r]/.test(data)) {
|
||||
throw new TypeError('Invalid data');
|
||||
}
|
||||
}
|
||||
|
||||
write(res: Response) {
|
||||
res.write('data: ' + this.data + '\n');
|
||||
}
|
||||
}
|
||||
|
||||
function getErrorObject(err: unknown) {
|
||||
if (err instanceof ResponseError) {
|
||||
return err.toJSON();
|
||||
}
|
||||
|
||||
if (err && typeof err === 'object' && 'type' in err && 'code' in err && 'message' in err && err.type === 'system') {
|
||||
return {
|
||||
error: 'unknown_error',
|
||||
error_message: err.message,
|
||||
error_code: err.code,
|
||||
...err,
|
||||
};
|
||||
}
|
||||
|
||||
if (err instanceof Error) {
|
||||
return {
|
||||
error: 'unknown_error',
|
||||
error_message: err.message,
|
||||
...err,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
error: 'unknown_error',
|
||||
error_message: (err as Error)?.message,
|
||||
...(err as object),
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user