fix(core):  effect error catching from middleware throwed error
MODIFY
packages/@integration/src/effects/user.effects.ts
packages/@integration/src/effects/user.effects.ts
-import { EffectFactory, combineRoutes } from '@marblejs/core';
-import { map, switchMap } from 'rxjs/operators';
+import { EffectFactory, combineRoutes, HttpError, HttpStatus } from '@marblejs/core';
+import { throwError } from 'rxjs';
+import { map, switchMap, catchError } from 'rxjs/operators';
import { Dao } from '../fakes/dao.fake';
import { authorize$ } from '../middlewares/auth.middleware';
@@ -18,6 +19,9 @@ const getUser$ = EffectFactory
map(req => req.params.id),
switchMap(Dao.getUserById),
map(user => ({ body: user })),
+ catchError(() =>
+ throwError(new HttpError('User does not exist', HttpStatus.NOT_FOUND))
+ )
));
const postUser$ = EffectFactory

MODIFY
packages/@integration/src/fakes/dao.fake.ts
packages/@integration/src/fakes/dao.fake.ts
-import { of } from 'rxjs';
+import { of, iif, throwError } from 'rxjs';
export namespace Dao {
@@ -8,9 +8,10 @@ export namespace Dao {
{ id: '3', firstName: 'Adam', lastName: 'Wayne' },
]);
- export const getUserById = (id: number | string) => of({
- id, firstName: 'Bob', lastName: 'Collins'
- });
+ export const getUserById = (id: number | string) =>
+ String(id) !== String(0)
+ ? of({ id, firstName: 'Bob', lastName: 'Collins' })
+ : throwError(new Error());
export const postUser = (data: any) => of({
data,

MODIFY
packages/@integration/test/integration.spec.ts
packages/@integration/test/integration.spec.ts
@@ -58,6 +58,17 @@ describe('API integration', () => {
expect(body.id).toEqual('10');
}));
+ test('GET returns 404 not found: /api/v1/user/0', async () =>
+ request(app)
+ .get('/api/v1/user/0')
+ .set('Authorization', 'Bearer FAKE')
+ .expect(404, { error: { status: 404, message: 'User does not exist' } }));
+
+ test('GET returns 401 if not authorized: /api/v1/user/10', async () =>
+ request(app)
+ .get('/api/v1/user/10')
+ .expect(401, { error: { status: 401, message: 'Unauthorized' } }));
+
test('parses POST body and returns echo for secured route: /api/v1/user', async () =>
request(app)
.post('/api/v1/user')

MODIFY
packages/core/src/router/router.ts
packages/core/src/router/router.ts
import { EMPTY, Observable, of } from 'rxjs';
+import { mergeMap } from 'rxjs/operators';
import { HttpMethod, HttpRequest, HttpResponse } from '../http.interface';
import { EffectResponse } from '../effects/effects.interface';
import { RouteMatched, Routing, RoutingItem } from './router.interface';
-import { queryParamsFactory } from '../router/queryParams.factory';
+import { queryParamsFactory } from './queryParams.factory';
export { RoutingItem };
export const findRoute = (
@@ -14,15 +15,11 @@ export const findRoute = (
const { regExp, methods } = routing[i];
const match = url.match(regExp);
- if (!match) {
- continue;
- }
+ if (!match) { continue; }
const routingMethod = methods[method] || methods['*'];
- if (!routingMethod) {
- continue;
- }
+ if (!routingMethod) { continue; }
const { parameters, effect, middleware } = routingMethod;
const params = {};
@@ -42,24 +39,21 @@ export const resolveRouting =
(routing: Routing) =>
(res: HttpResponse) =>
(req: HttpRequest): Observable<EffectResponse> => {
- if (res.finished) {
- return EMPTY;
- }
+ if (res.finished) { return EMPTY; }
const [urlPath, urlQuery] = req.url.split('?');
const routeMatched = findRoute(routing, urlPath, req.method);
- if (!routeMatched) {
- return EMPTY;
- }
+ if (!routeMatched) { return EMPTY; }
req.query = queryParamsFactory(urlQuery);
req.params = routeMatched.params;
const middleware = routeMatched.middleware;
- const req$ = of(req);
return middleware
- ? routeMatched.effect(middleware(req$, res, null), res, null)
- : routeMatched.effect(req$, res, null);
+ ? middleware(of(req), res, null).pipe(
+ mergeMap(req => routeMatched.effect(of(req), res, null))
+ )
+ : routeMatched.effect(of(req), res, null);
};

fix(core):  effect error catching from middleware throwed error