feature - error catcher middleware - refactor
MODIFY
src/http.listener.ts
src/http.listener.ts
@@ -2,16 +2,17 @@ import { Subject, of } from 'rxjs';
import { catchError, defaultIfEmpty, switchMap, tap } from 'rxjs/operators';
import { Effect, combineEffects, combineMiddlewareEffects } from './effects';
import { Http, HttpRequest, HttpResponse } from './http.interface';
-import { errorCatcher$ } from './middlewares/errorCatcher.middleware';
+import { getErrorMiddleware } from './middlewares/errorCatcher.middleware';
import { handleResponse } from './response';
import { StatusCode } from './util';
type HttpListenerConfig = {
middlewares: Effect<HttpRequest>[],
effects: Effect[],
+ errorMiddleware?: Effect<HttpRequest, Error>,
};
-export const httpListener = ({ middlewares, effects }: HttpListenerConfig) => {
+export const httpListener = ({ middlewares, effects, errorMiddleware }: HttpListenerConfig) => {
const request$ = new Subject<Http>();
const effect$ = request$
.pipe(
@@ -21,7 +22,7 @@ export const httpListener = ({ middlewares, effects }: HttpListenerConfig) => {
switchMap(combineEffects(effects)(res)),
defaultIfEmpty({ status: StatusCode.NOT_FOUND }),
tap(handleResponse(res)),
- catchError(error => errorCatcher$(of(req), res, error))
+ catchError(error => getErrorMiddleware(errorMiddleware)(of(req), res, error))
)
)
);

MODIFY
src/middlewares/bodyParser.middleware.ts
src/middlewares/bodyParser.middleware.ts
@@ -2,8 +2,8 @@ import { Observable, throwError } from 'rxjs';
import { catchError, map, switchMap, tap, toArray } from 'rxjs/operators';
import { Effect } from '../effects';
import { HttpRequest } from '../http.interface';
-import { ContentType } from '../util';
-import { ServerError } from '../util/error.util';
+import { ContentType, StatusCode } from '../util';
+import { HttpError } from '../util/error.util';
export const fromReadableStream = (stream: HttpRequest): Observable<any> => {
stream.pause();
@@ -50,7 +50,7 @@ export const bodyParser$: Effect<HttpRequest> = (request$, response) => request$
switchMap(getBody),
tap(body => req.body = body),
map(body => req),
- catchError(error => throwError(new ServerError('Request body parse error', error)))
+ catchError(error => throwError(new HttpError('Request body parse error', StatusCode.BAD_REQUEST)))
)
: request$
)

MODIFY
src/middlewares/errorCatcher.middleware.ts
src/middlewares/errorCatcher.middleware.ts
@@ -3,32 +3,28 @@ import { Effect } from '../effects';
import { HttpRequest } from '../http.interface';
import { DEFAULT_HEADERS } from '../response';
import { StatusCode } from '../util';
-import { HttpError, ServerError, isHttpError, isServerError } from '../util/error.util';
+import { HttpError, isHttpError } from '../util/error.util';
-export type Error = HttpError | ServerError;
+export type Error = HttpError;
-export const getStatusCode = (error: Error): StatusCode => {
- if (isServerError(error)) {
- return StatusCode.BAD_REQUEST;
- }
+export const getErrorMiddleware = (customErrorCatcher$?: Effect<HttpRequest, Error>) => !!customErrorCatcher$
+ ? customErrorCatcher$
+ : errorCatcher$;
- if (isHttpError(error)) {
- return error.status;
- }
+export const getStatusCode = (error: Error): StatusCode => isHttpError(error)
+ ? error.status
+ : StatusCode.INTERNAL_SERVER_ERROR;
- return StatusCode.INTERNAL_SERVER_ERROR;
-};
+export const errorFactory = (message: string, status: StatusCode, data?: any) => ({
+ error: { status, message, data }
+});
export const errorCatcher$: Effect<HttpRequest, Error> = (request$, response, error) => request$
.pipe(
tap(req => {
+ const { message } = error;
const status = getStatusCode(error);
- const errorObject = {
- error: {
- status,
- message: error.message,
- },
- };
+ const errorObject = errorFactory(message, status);
response.writeHead(status, DEFAULT_HEADERS);
response.end(JSON.stringify(errorObject));

MODIFY
src/util/error.util.ts
src/util/error.util.ts
@@ -18,17 +18,5 @@ export class HttpError extends ExtendableError {
}
}
-export class ServerError extends ExtendableError {
- constructor(
- public readonly message: string,
- public readonly error: any,
- ) {
- super('ServerError', message);
- }
-}
-
export const isHttpError = (error: Error): error is HttpError =>
error.name === 'HttpError';
-
-export const isServerError = (error: Error): error is ServerError =>
- error.name === 'ServerError';

feature - error catcher middleware - refactor