refactor - error middleware - return `EffectResponse` for `responseHandler`
MODIFY
src/http.listener.ts
src/http.listener.ts
import { Subject, of } from 'rxjs';
import { catchError, defaultIfEmpty, switchMap, tap } from 'rxjs/operators';
-import { Effect, combineEffects, combineMiddlewareEffects } from './effects';
+import { Effect, EffectResponse, combineEffects, combineMiddlewareEffects } from './effects';
import { Http, HttpRequest, HttpResponse } from './http.interface';
-import { getErrorMiddleware } from './middlewares/errorCatcher.middleware';
+import { getErrorMiddleware } from './middlewares';
import { handleResponse } from './response';
import { StatusCode } from './util';
type HttpListenerConfig = {
middlewares: Effect<HttpRequest>[],
effects: Effect[],
- errorMiddleware?: Effect<HttpRequest, Error>,
+ errorMiddleware?: Effect<EffectResponse, Error>,
};
export const httpListener = ({ middlewares, effects, errorMiddleware }: HttpListenerConfig) => {
@@ -22,7 +22,12 @@ export const httpListener = ({ middlewares, effects, errorMiddleware }: HttpList
switchMap(combineEffects(effects)(res)),
defaultIfEmpty({ status: StatusCode.NOT_FOUND }),
tap(handleResponse(res)),
- catchError(error => getErrorMiddleware(errorMiddleware)(of(req), res, error))
+ catchError(error =>
+ getErrorMiddleware(errorMiddleware)(of(req), res, error)
+ .pipe(
+ tap(handleResponse(res)),
+ ),
+ )
)
)
);

ADD
src/middlewares/error.middleware.ts
+import { map } from 'rxjs/operators';
+import { Effect, EffectResponse } from '../effects';
+import { StatusCode } from '../util';
+import { HttpError, isHttpError } from '../util/error.util';
+
+export type Error = HttpError;
+
+export const getErrorMiddleware = (customError$?: Effect<EffectResponse, Error>) => !!customError$
+ ? customError$
+ : error$;
+
+export const getStatusCode = (error: Error): StatusCode => isHttpError(error)
+ ? error.status
+ : StatusCode.INTERNAL_SERVER_ERROR;
+
+export const errorFactory = (message: string, status: StatusCode, data?: any) => ({
+ error: { status, message, data }
+});
+
+export const error$: Effect<EffectResponse, Error> = (request$, response, error) => request$
+ .pipe(
+ map(req => {
+ const { message } = error;
+ const status = getStatusCode(error);
+ const body = errorFactory(message, status);
+
+ return { status, body };
+ }),
+ );

DELETE
src/middlewares/errorCatcher.middleware.ts
-import { tap } from 'rxjs/operators';
-import { Effect } from '../effects';
-import { HttpRequest } from '../http.interface';
-import { DEFAULT_HEADERS } from '../response';
-import { StatusCode } from '../util';
-import { HttpError, isHttpError } from '../util/error.util';
-
-export type Error = HttpError;
-
-export const getErrorMiddleware = (customErrorCatcher$?: Effect<HttpRequest, Error>) => !!customErrorCatcher$
- ? customErrorCatcher$
- : errorCatcher$;
-
-export const getStatusCode = (error: Error): StatusCode => isHttpError(error)
- ? error.status
- : 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 = errorFactory(message, status);
-
- response.writeHead(status, DEFAULT_HEADERS);
- response.end(JSON.stringify(errorObject));
- })
- );

MODIFY
src/middlewares/index.ts
src/middlewares/index.ts
export * from './bodyParser.middleware';
export * from './logger.middleware';
-export * from './errorCatcher.middleware';
+export * from './error.middleware';

refactor - error middleware - return `EffectResponse` for `responseHandler`