mirror of
https://github.com/logto-io/logto.git
synced 2025-02-17 22:04:19 -05:00
feat(core): align connector error handler middleware with ConnectorErrorCodes (#1063)
* feat(core): align connector error handler middleware with ConnectorErrorCodes * feat(phrases,core): fix locale error descriptions
This commit is contained in:
parent
36dda2bdbb
commit
1b8190addf
7 changed files with 213 additions and 12 deletions
|
@ -9,7 +9,7 @@ import mount from 'koa-mount';
|
|||
|
||||
import envSet, { MountedApps } from '@/env-set';
|
||||
import koaCheckDemoApp from '@/middleware/koa-check-demo-app';
|
||||
import koaConnectorErrorHandler from '@/middleware/koa-connector-error-handle';
|
||||
import koaConnectorErrorHandler from '@/middleware/koa-connector-error-handler';
|
||||
import koaErrorHandler from '@/middleware/koa-error-handler';
|
||||
import koaI18next from '@/middleware/koa-i18next';
|
||||
import koaLog from '@/middleware/koa-log';
|
||||
|
|
169
packages/core/src/middleware/koa-connector-error-handler.test.ts
Normal file
169
packages/core/src/middleware/koa-connector-error-handler.test.ts
Normal file
|
@ -0,0 +1,169 @@
|
|||
import { ConnectorError, ConnectorErrorCodes } from '@logto/connector-types';
|
||||
|
||||
import RequestError from '@/errors/RequestError';
|
||||
import { createContextWithRouteParameters } from '@/utils/test-utils';
|
||||
|
||||
import koaConnectorErrorHandler from './koa-connector-error-handler';
|
||||
|
||||
describe('koaConnectorErrorHandler middleware', () => {
|
||||
const next = jest.fn();
|
||||
const ctx = createContextWithRouteParameters();
|
||||
|
||||
it('should throw no errors if no errors are caught', async () => {
|
||||
await expect(koaConnectorErrorHandler()(ctx, next)).resolves.not.toThrow();
|
||||
});
|
||||
|
||||
it('should throw original error if error type is not ConnectorError', async () => {
|
||||
const error = new Error('err');
|
||||
|
||||
next.mockImplementationOnce(() => {
|
||||
throw error;
|
||||
});
|
||||
|
||||
await expect(koaConnectorErrorHandler()(ctx, next)).rejects.toMatchError(error);
|
||||
});
|
||||
|
||||
it('Insufficient Request Parameters', async () => {
|
||||
const message = 'Mock Insufficient Request Parameters';
|
||||
const error = new ConnectorError(ConnectorErrorCodes.InsufficientRequestParameters, message);
|
||||
next.mockImplementationOnce(() => {
|
||||
throw error;
|
||||
});
|
||||
|
||||
await expect(koaConnectorErrorHandler()(ctx, next)).rejects.toMatchError(
|
||||
new RequestError(
|
||||
{
|
||||
code: 'connector.insufficient_request_parameters',
|
||||
status: 400,
|
||||
},
|
||||
{ message }
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
it('Invalid Config', async () => {
|
||||
const message = 'Mock Invalid Config';
|
||||
const error = new ConnectorError(ConnectorErrorCodes.InvalidConfig, message);
|
||||
next.mockImplementationOnce(() => {
|
||||
throw error;
|
||||
});
|
||||
|
||||
await expect(koaConnectorErrorHandler()(ctx, next)).rejects.toMatchError(
|
||||
new RequestError(
|
||||
{
|
||||
code: 'connector.invalid_config',
|
||||
status: 400,
|
||||
},
|
||||
{ message }
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
it('Invalid Response', async () => {
|
||||
const message = 'Mock Invalid Response';
|
||||
const error = new ConnectorError(ConnectorErrorCodes.InvalidResponse, message);
|
||||
next.mockImplementationOnce(() => {
|
||||
throw error;
|
||||
});
|
||||
|
||||
await expect(koaConnectorErrorHandler()(ctx, next)).rejects.toMatchError(
|
||||
new RequestError(
|
||||
{
|
||||
code: 'connector.invalid_response',
|
||||
status: 400,
|
||||
},
|
||||
{ message }
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
it('Template Not Found', async () => {
|
||||
const message = 'Mock Template Not Found';
|
||||
const error = new ConnectorError(ConnectorErrorCodes.TemplateNotFound, message);
|
||||
next.mockImplementationOnce(() => {
|
||||
throw error;
|
||||
});
|
||||
|
||||
await expect(koaConnectorErrorHandler()(ctx, next)).rejects.toMatchError(
|
||||
new RequestError(
|
||||
{
|
||||
code: 'connector.template_not_found',
|
||||
status: 500,
|
||||
},
|
||||
{ message }
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
it('Social Auth Code Invalid', async () => {
|
||||
const message = 'Mock Social Auth Code Invalid';
|
||||
const error = new ConnectorError(ConnectorErrorCodes.SocialAuthCodeInvalid, message);
|
||||
next.mockImplementationOnce(() => {
|
||||
throw error;
|
||||
});
|
||||
|
||||
await expect(koaConnectorErrorHandler()(ctx, next)).rejects.toMatchError(
|
||||
new RequestError(
|
||||
{
|
||||
code: 'connector.oauth_code_invalid',
|
||||
status: 401,
|
||||
},
|
||||
{ message }
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
it('Social Access Token Invalid', async () => {
|
||||
const message = 'Mock Social Access Token Invalid';
|
||||
const error = new ConnectorError(ConnectorErrorCodes.SocialAccessTokenInvalid, message);
|
||||
next.mockImplementationOnce(() => {
|
||||
throw error;
|
||||
});
|
||||
|
||||
await expect(koaConnectorErrorHandler()(ctx, next)).rejects.toMatchError(
|
||||
new RequestError(
|
||||
{
|
||||
code: 'connector.invalid_access_token',
|
||||
status: 401,
|
||||
},
|
||||
{ message }
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
it('Social Id Token Invalid', async () => {
|
||||
const message = 'Mock Social Id Token Invalid';
|
||||
const error = new ConnectorError(ConnectorErrorCodes.SocialIdTokenInvalid, message);
|
||||
next.mockImplementationOnce(() => {
|
||||
throw error;
|
||||
});
|
||||
|
||||
await expect(koaConnectorErrorHandler()(ctx, next)).rejects.toMatchError(
|
||||
new RequestError(
|
||||
{
|
||||
code: 'connector.invalid_id_token',
|
||||
status: 401,
|
||||
},
|
||||
{ message }
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
it('General connector errors', async () => {
|
||||
const message = 'Mock General connector errors';
|
||||
const error = new ConnectorError(ConnectorErrorCodes.General, message);
|
||||
next.mockImplementationOnce(() => {
|
||||
throw error;
|
||||
});
|
||||
|
||||
await expect(koaConnectorErrorHandler()(ctx, next)).rejects.toMatchError(
|
||||
new RequestError(
|
||||
{
|
||||
code: 'connector.general',
|
||||
status: 500,
|
||||
},
|
||||
{ message }
|
||||
)
|
||||
);
|
||||
});
|
||||
});
|
|
@ -18,6 +18,14 @@ export default function koaConnectorErrorHandler<StateT, ContextT>(): Middleware
|
|||
const data = { message };
|
||||
|
||||
switch (code) {
|
||||
case ConnectorErrorCodes.InsufficientRequestParameters:
|
||||
throw new RequestError(
|
||||
{
|
||||
code: 'connector.insufficient_request_parameters',
|
||||
status: 400,
|
||||
},
|
||||
data
|
||||
);
|
||||
case ConnectorErrorCodes.InvalidConfig:
|
||||
throw new RequestError(
|
||||
{
|
||||
|
@ -26,11 +34,19 @@ export default function koaConnectorErrorHandler<StateT, ContextT>(): Middleware
|
|||
},
|
||||
data
|
||||
);
|
||||
case ConnectorErrorCodes.SocialAccessTokenInvalid:
|
||||
case ConnectorErrorCodes.InvalidResponse:
|
||||
throw new RequestError(
|
||||
{
|
||||
code: 'connector.access_token_invalid',
|
||||
status: 401,
|
||||
code: 'connector.invalid_response',
|
||||
status: 400,
|
||||
},
|
||||
data
|
||||
);
|
||||
case ConnectorErrorCodes.TemplateNotFound:
|
||||
throw new RequestError(
|
||||
{
|
||||
code: 'connector.template_not_found',
|
||||
status: 500,
|
||||
},
|
||||
data
|
||||
);
|
||||
|
@ -42,11 +58,19 @@ export default function koaConnectorErrorHandler<StateT, ContextT>(): Middleware
|
|||
},
|
||||
data
|
||||
);
|
||||
case ConnectorErrorCodes.TemplateNotFound:
|
||||
case ConnectorErrorCodes.SocialAccessTokenInvalid:
|
||||
throw new RequestError(
|
||||
{
|
||||
code: 'connector.template_not_found',
|
||||
status: 500,
|
||||
code: 'connector.invalid_access_token',
|
||||
status: 401,
|
||||
},
|
||||
data
|
||||
);
|
||||
case ConnectorErrorCodes.SocialIdTokenInvalid:
|
||||
throw new RequestError(
|
||||
{
|
||||
code: 'connector.invalid_id_token',
|
||||
status: 401,
|
||||
},
|
||||
data
|
||||
);
|
|
@ -9,11 +9,11 @@ describe('koaOIDCErrorHandler middleware', () => {
|
|||
const next = jest.fn();
|
||||
const ctx = createContextWithRouteParameters();
|
||||
|
||||
it('should throw no errors if no errors are catched', async () => {
|
||||
it('should throw no errors if no errors are caught', async () => {
|
||||
await expect(koaOIDCErrorHandler()(ctx, next)).resolves.not.toThrow();
|
||||
});
|
||||
|
||||
it('should throw original error if error type is no OIDCProviderError', async () => {
|
||||
it('should throw original error if error type is not OIDCProviderError', async () => {
|
||||
const error = new Error('err');
|
||||
|
||||
next.mockImplementationOnce(() => {
|
||||
|
|
|
@ -11,7 +11,7 @@ describe('koaSlonikErrorHandler middleware', () => {
|
|||
const next = jest.fn();
|
||||
const ctx = createContextWithRouteParameters();
|
||||
|
||||
it('should throw no errors if no errors are catched', async () => {
|
||||
it('should throw no errors if no errors are caught', async () => {
|
||||
await expect(koaSlonikErrorHandler()(ctx, next)).resolves.not.toThrow();
|
||||
});
|
||||
|
||||
|
|
|
@ -639,9 +639,13 @@ const errors = {
|
|||
general: 'An unexpected error occurred in connector.',
|
||||
not_found: 'Cannot find any available connector for type: {{type}}.',
|
||||
not_enabled: 'The connector is not enabled.',
|
||||
insufficient_request_parameters: 'The request might miss some input parameters.',
|
||||
invalid_config: "The connector's config is invalid.",
|
||||
invalid_response: "The connector's response is invalid.",
|
||||
template_not_found: 'Unable to find correct template in connector config.',
|
||||
access_token_invalid: "Connector's access token is invalid.",
|
||||
invalid_access_token: "The connector's access token is invalid.",
|
||||
invalid_auth_code: "The connector's auth code is invalid.",
|
||||
invalid_id_token: "The connector's id token is invalid.",
|
||||
oauth_code_invalid: 'Unable to get access token, please check authorization code.',
|
||||
more_than_one_sms: 'The number of SMS connectors is larger then 1.',
|
||||
more_than_one_email: 'The number of Email connectors is larger then 1.',
|
||||
|
|
|
@ -621,9 +621,13 @@ const errors = {
|
|||
general: '连接器发生未知错误。',
|
||||
not_found: '找不到可用的 {{type}} 类型的连接器。',
|
||||
not_enabled: '连接器尚未启用。',
|
||||
insufficient_request_parameters: '请求参数缺失。',
|
||||
invalid_config: '连接器配置错误。',
|
||||
invalid_response: '连接器错误响应。',
|
||||
template_not_found: '无法从连接器配置中找到对应的模板。',
|
||||
access_token_invalid: '当前连接器的 access_token 无效。',
|
||||
invalid_access_token: '当前连接器的 access_token 无效。',
|
||||
invalid_auth_code: '当前连接器的授权码无效。',
|
||||
invalid_id_token: '当前连接器的 id_token 无效。',
|
||||
oauth_code_invalid: '无法获取 access_token,请检查授权 code 是否有效。',
|
||||
more_than_one_sms: '同时存在超过 1 个短信连接器。',
|
||||
more_than_one_email: '同时存在超过 1 个邮件连接器。',
|
||||
|
|
Loading…
Add table
Reference in a new issue