Skip to content

Commit

Permalink
refactor(core): dont throw for status errors in prod
Browse files Browse the repository at this point in the history
  • Loading branch information
gao-sun committed Apr 12, 2024
1 parent 97f2d9b commit 5d2f4cb
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 9 deletions.
5 changes: 5 additions & 0 deletions .changeset/cuddly-buses-obey.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@logto/core": patch
---

Management API will not return 500 in production for status codes that are not listed in the OpenAPI spec
21 changes: 21 additions & 0 deletions packages/core/src/middleware/koa-guard.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { createMockUtils } from '@logto/shared/esm';
import { z } from 'zod';

import { EnvSet } from '#src/env-set/index.js';
import RequestError from '#src/errors/RequestError/index.js';
import ServerError from '#src/errors/ServerError/index.js';
import { emptyMiddleware, createContextWithRouteParameters } from '#src/utils/test-utils.js';
Expand Down Expand Up @@ -135,6 +136,26 @@ describe('koaGuardMiddleware', () => {
await expect(koaGuard({ status: [200, 204] })(ctx, next)).rejects.toThrow(ServerError);
});

it('should not throw when status is invalid in production', async () => {
const ctx = {
...baseCtx,
params: {},
body: {},
guard: {},
response: { status: 301 },
};
const { isProduction } = EnvSet.values;

// eslint-disable-next-line @silverhand/fp/no-mutating-assign
Object.assign(EnvSet.values, { isProduction: true });
// @ts-expect-error
await expect(koaGuard({ status: 200 })(ctx, next)).resolves.toBeUndefined();
// @ts-expect-error
await expect(koaGuard({ status: [200, 204] })(ctx, next)).resolves.toBeUndefined();
// eslint-disable-next-line @silverhand/fp/no-mutating-assign
Object.assign(EnvSet.values, { isProduction });
});

it('should throw when inner middleware throws invalid status', async () => {
const ctx = {
...baseCtx,
Expand Down
23 changes: 14 additions & 9 deletions packages/core/src/middleware/koa-guard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import type { ZodType, ZodTypeDef } from 'zod';
import { EnvSet } from '#src/env-set/index.js';
import RequestError from '#src/errors/RequestError/index.js';
import { ResponseBodyError, StatusCodeError } from '#src/errors/ServerError/index.js';
import assertThat from '#src/utils/assert-that.js';
import { consoleLog } from '#src/utils/console.js';

/** Configure what and how to guard. */
Expand Down Expand Up @@ -174,6 +173,9 @@ export default function koaGuard<
* Assert the status code matches the value(s) in the config. If the config does not
* specify a status code, it will not assert anything.
*
* In production, it will log a warning if the status code does not match the value(s) in the
* config for better user experience.
*
* @param value The status code to assert.
* @throws {StatusCodeError} If the status code does not match the value(s) in the config.
*/
Expand All @@ -182,10 +184,16 @@ export default function koaGuard<
return;
}

assertThat(
Array.isArray(status) ? status.includes(value) : status === value,
new StatusCodeError(status, value)
);
if (Array.isArray(status) ? status.includes(value) : status === value) {
return;
}

if (EnvSet.values.isProduction) {
consoleLog.warn('Unexpected status code:', value, 'expected:', status);
return;
}

throw new StatusCodeError(status, value);
};

try {
Expand Down Expand Up @@ -215,10 +223,7 @@ export default function koaGuard<
// the properties that are not defined in the schema.
ctx.body = result.data;
} else {
if (!EnvSet.values.isProduction) {
consoleLog.error('Invalid response:', result.error);
}

consoleLog.error('Invalid response:', result.error);
throw new ResponseBodyError(result.error);
}
}
Expand Down

0 comments on commit 5d2f4cb

Please sign in to comment.