refactor: Split off ErrorResponseWriter

This commit is contained in:
Joachim Van Herwegen
2020-10-26 12:05:39 +01:00
parent f4161d406c
commit e8fdcb0ad0
18 changed files with 150 additions and 72 deletions

View File

@@ -1,49 +1,37 @@
import { getLoggerFor } from '../../logging/LogUtil';
import type { HttpResponse } from '../../server/HttpResponse';
import { HttpError } from '../../util/errors/HttpError';
import { UnsupportedHttpError } from '../../util/errors/UnsupportedHttpError';
import type { ResponseDescription } from '../operations/ResponseDescription';
import { ResponseWriter } from './ResponseWriter';
/**
* Writes to an {@link HttpResponse} based on the incoming {@link ResponseDescription} or error.
* Writes to an {@link HttpResponse} based on the incoming {@link ResponseDescription}.
* Still needs a way to write correct status codes for successful operations.
*/
export class BasicResponseWriter extends ResponseWriter {
protected readonly logger = getLoggerFor(this);
public async canHandle(input: { response: HttpResponse; result: ResponseDescription | Error }): Promise<void> {
if (!(input.result instanceof Error) && input.result.body && !input.result.body.binary) {
this.logger.warn('This writer can only write binary bodies and errors');
throw new UnsupportedHttpError('Only binary results and errors are supported');
if ((input.result instanceof Error) || (input.result.body && !input.result.body.binary)) {
this.logger.warn('This writer can only write binary bodies');
throw new UnsupportedHttpError('Only binary results are supported');
}
}
public async handle(input: { response: HttpResponse; result: ResponseDescription | Error }): Promise<void> {
if (input.result instanceof Error) {
let code = 500;
if (input.result instanceof HttpError) {
code = input.result.statusCode;
}
input.response.setHeader('content-type', 'text/plain');
input.response.writeHead(code);
input.response.end(typeof input.result.stack === 'string' ?
`${input.result.stack}\n` :
`${input.result.name}: ${input.result.message}\n`);
public async handle(input: { response: HttpResponse; result: ResponseDescription }): Promise<void> {
input.response.setHeader('location', input.result.identifier.path);
if (input.result.body) {
const contentType = input.result.body.metadata.contentType ?? 'text/plain';
input.response.setHeader('content-type', contentType);
}
input.response.writeHead(200);
if (input.result.body) {
input.result.body.data.pipe(input.response);
} else {
input.response.setHeader('location', input.result.identifier.path);
if (input.result.body) {
const contentType = input.result.body.metadata.contentType ?? 'text/plain';
input.response.setHeader('content-type', contentType);
input.result.body.data.pipe(input.response);
}
input.response.writeHead(200);
if (!input.result.body) {
// If there is an input body the response will end once the input stream ends
input.response.end();
}
// If there is an input body the response will end once the input stream ends
input.response.end();
}
}
}

View File

@@ -0,0 +1,32 @@
import { getLoggerFor } from '../../logging/LogUtil';
import type { HttpResponse } from '../../server/HttpResponse';
import { HttpError } from '../../util/errors/HttpError';
import { UnsupportedHttpError } from '../../util/errors/UnsupportedHttpError';
import type { ResponseDescription } from '../operations/ResponseDescription';
import { ResponseWriter } from './ResponseWriter';
/**
* Writes to an {@link HttpResponse} based on the incoming Error.
*/
export class ErrorResponseWriter extends ResponseWriter {
protected readonly logger = getLoggerFor(this);
public async canHandle(input: { response: HttpResponse; result: ResponseDescription | Error }): Promise<void> {
if (!(input.result instanceof Error)) {
this.logger.warn('This writer can only write errors');
throw new UnsupportedHttpError('Only errors are supported');
}
}
public async handle(input: { response: HttpResponse; result: Error }): Promise<void> {
let code = 500;
if (input.result instanceof HttpError) {
code = input.result.statusCode;
}
input.response.setHeader('content-type', 'text/plain');
input.response.writeHead(code);
input.response.end(typeof input.result.stack === 'string' ?
`${input.result.stack}\n` :
`${input.result.name}: ${input.result.message}\n`);
}
}