Skip to content

Commit

Permalink
fix(logger): logger should display the right status code in case of e…
Browse files Browse the repository at this point in the history
…rror (#1194)
  • Loading branch information
Thenkei authored Oct 15, 2024
1 parent 1fd3669 commit d328764
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 14 deletions.
3 changes: 3 additions & 0 deletions packages/agent/src/routes/system/error-handling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ export default class ErrorHandling extends BaseRoute {
if (!this.options.isProduction) {
process.nextTick(() => this.debugLogError(context, e));
}

// The error will be used by Logger
throw e;
}
}

Expand Down
1 change: 0 additions & 1 deletion packages/agent/src/routes/system/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ export default class Logger extends BaseRoute {
await next();
} catch (e) {
error = e;
throw e;
} finally {
let logLevel: LoggerLevel = 'Info';
if (context.response.status >= HttpCode.BadRequest) logLevel = 'Warn';
Expand Down
4 changes: 2 additions & 2 deletions packages/agent/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ export enum HttpCode {

export enum RouteType {
// Changing the values of this enum changes the order in which routes are loaded into koa-router.
ErrorHandler = 0,
LoggerHandler = 1,
LoggerHandler = 0,
ErrorHandler = 1,
PublicRoute = 2,
Authentication = 3,
PrivateRoute = 4,
Expand Down
17 changes: 17 additions & 0 deletions packages/agent/test/routes/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import ScopeInvalidation from '../../src/routes/security/scope-invalidation';
import ErrorHandling from '../../src/routes/system/error-handling';
import HealthCheck from '../../src/routes/system/healthcheck';
import Logger from '../../src/routes/system/logger';
import { RouteType } from '../../src/types';
import * as factories from '../__factories__';

describe('Route index', () => {
Expand Down Expand Up @@ -81,6 +82,22 @@ describe('Route index', () => {
const countCollectionRoutes = COLLECTION_ROUTES_CTOR.length * dataSource.collections.length;
expect(routes.length).toEqual(ROOT_ROUTES_CTOR.length + countCollectionRoutes);
});

test('should order routes correctly', async () => {
const dataSource = setupWithoutRelation();

const routes = makeRoutes(
dataSource,
factories.forestAdminHttpDriverOptions.build(),
factories.forestAdminHttpDriverServices.build(),
);

// with LoggerHandler in first
expect(routes[0].type).toEqual(RouteType.LoggerHandler);

// followed by ErrorHandler
expect(routes[1].type).toEqual(RouteType.ErrorHandler);
});
});

describe('when a data source with an one to many relation', () => {
Expand Down
21 changes: 11 additions & 10 deletions packages/agent/test/routes/system/error-handling.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ describe('ErrorHandling', () => {
const context = createMockContext();
const next = jest.fn().mockRejectedValue(new ValidationError('hello'));

await handleError.call(route, context, next);
await expect(handleError.call(route, context, next)).rejects.toThrow();

expect(context.response.status).toStrictEqual(HttpCode.BadRequest);
expect(context.response.body).toStrictEqual({
Expand All @@ -84,7 +84,7 @@ describe('ErrorHandling', () => {
const context = createMockContext();
const next = jest.fn().mockRejectedValue(new BadRequestError('message'));

await handleError.call(route, context, next);
await expect(handleError.call(route, context, next)).rejects.toThrow();

expect(context.response.status).toStrictEqual(HttpCode.BadRequest);
expect(context.response.body).toStrictEqual({
Expand All @@ -97,7 +97,7 @@ describe('ErrorHandling', () => {
const context = createMockContext();
const next = jest.fn().mockRejectedValue(new UnprocessableError('message'));

await handleError.call(route, context, next);
await expect(handleError.call(route, context, next)).rejects.toThrow();

expect(context.response.status).toStrictEqual(HttpCode.Unprocessable);
expect(context.response.body).toStrictEqual({
Expand All @@ -110,7 +110,7 @@ describe('ErrorHandling', () => {
const context = createMockContext();
const next = jest.fn().mockRejectedValue(new ForbiddenError('forbidden'));

await handleError.call(route, context, next);
await expect(handleError.call(route, context, next)).rejects.toThrow();

expect(context.response.status).toStrictEqual(HttpCode.Forbidden);
expect(context.response.body).toStrictEqual({
Expand All @@ -123,7 +123,7 @@ describe('ErrorHandling', () => {
const context = createMockContext();
const next = jest.fn().mockRejectedValue(new NotFoundError('message'));

await handleError.call(route, context, next);
await expect(handleError.call(route, context, next)).rejects.toThrow();

expect(context.response.status).toStrictEqual(HttpCode.NotFound);
expect(context.response.body).toStrictEqual({
Expand All @@ -138,7 +138,7 @@ describe('ErrorHandling', () => {
.fn()
.mockRejectedValue(new Error('Internal error with important data that should not leak'));

await handleError.call(route, context, next);
await expect(handleError.call(route, context, next)).rejects.toThrow();

expect(context.response.status).toStrictEqual(HttpCode.InternalServerError);
expect(context.response.body).toStrictEqual({
Expand All @@ -151,7 +151,7 @@ describe('ErrorHandling', () => {
const context = createMockContext();
const next = jest.fn().mockRejectedValue(new Error('My Error'));

await handleError.call(route, context, next);
await expect(handleError.call(route, context, next)).rejects.toThrow();

expect(context.response.status).toStrictEqual(HttpCode.InternalServerError);
expect(context.response.body).toStrictEqual({
Expand All @@ -165,7 +165,7 @@ describe('ErrorHandling', () => {
const context = createMockContext();
const next = jest.fn().mockRejectedValue(new FakePayloadError('message'));

await handleError.call(route, context, next);
await expect(handleError.call(route, context, next)).rejects.toThrow();

expect(context.response.status).toStrictEqual(HttpCode.Forbidden);
expect(context.response.body).toStrictEqual({
Expand Down Expand Up @@ -196,7 +196,7 @@ describe('ErrorHandling', () => {

const next = jest.fn().mockRejectedValue(fakeErrorFromDependency);

await handleError.call(route, context, next);
await expect(handleError.call(route, context, next)).rejects.toThrow();

expect(context.response.status).toStrictEqual(HttpCode.InternalServerError);
expect(context.response.body).toStrictEqual({
Expand Down Expand Up @@ -233,7 +233,8 @@ describe('ErrorHandling', () => {
const context = createMockContext({ method: 'POST' });
const next = jest.fn().mockRejectedValue(new Error('Internal error'));

await handleError.call(route, context, next);
await expect(handleError.call(route, context, next)).rejects.toThrow();

await new Promise(setImmediate);

expect(console.error).toHaveBeenCalled();
Expand Down
3 changes: 2 additions & 1 deletion packages/agent/test/routes/system/logger.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ describe('Logger', () => {
};
const next = jest.fn().mockRejectedValue(error);

await expect(handleLog.call(route, context, next)).rejects.toThrow('RouteError');
await expect(handleLog.call(route, context, next)).toResolve();

expect(options.logger).toHaveBeenCalledWith('Error', '[500] GET someUrl - 0ms', error);
});
});
Expand Down

0 comments on commit d328764

Please sign in to comment.