Skip to content

Commit

Permalink
feat: Improve Monobank pairing error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
letehaha committed Sep 21, 2024
1 parent 9dcb8af commit 6cb23b0
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 23 deletions.
2 changes: 1 addition & 1 deletion src/controllers/banks/monobank.controller.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ describe('Monobank integration', () => {
it('throws error if invalid "token" is passed', async () => {
const result = await helpers.monobank.callPair();

expect(result.status).toEqual(ERROR_CODES.NotFoundError);
expect(result.status).toEqual(ERROR_CODES.Forbidden);
});
it('creates Monobank user and correct accounts with valid token', async () => {
const mockedClientData = helpers.monobank.mockedClient();
Expand Down
15 changes: 15 additions & 0 deletions src/js/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { API_ERROR_CODES } from 'shared-types';
export enum ERROR_CODES {
BadRequest = 400,
Unauthorized = 401,
Forbidden = 403,
NotFoundError = 404,
ConflictError = 409,
ValidationError = 422,
Expand Down Expand Up @@ -88,6 +89,20 @@ export class ValidationError extends CustomError {
}
}

export class ForbiddenError extends CustomError {
constructor({
code = API_ERROR_CODES.forbidden,
message,
details,
}: {
code?: API_ERROR_CODES;
message: string;
details?: Record<string, unknown>;
}) {
super(ERROR_CODES.Forbidden, code, message, details);
}
}

export class UnexpectedError extends CustomError {
constructor(code: API_ERROR_CODES, message: string) {
super(ERROR_CODES.UnexpectedError, code, message);
Expand Down
58 changes: 36 additions & 22 deletions src/services/accounts.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import * as monobankUsersService from '@services/banks/monobank/users';
import * as Currencies from '@models/Currencies.model';
import { addUserCurrencies } from '@services/currencies/add-user-currency';
import { redisClient } from '@root/redis';
import { NotFoundError, UnexpectedError } from '@js/errors';
import { ForbiddenError, NotFoundError, UnexpectedError } from '@js/errors';
import Balances from '@models/Balances.model';
import { calculateRefAmount } from '@services/calculate-ref-amount.service';
import { withTransaction } from './common';
Expand Down Expand Up @@ -107,29 +107,43 @@ export const pairMonobankAccount = withTransaction(
// TODO: setup it later
// await updateWebhookAxios({ userToken: token });

const result = await axios({
method: 'GET',
url: `${hostname}/personal/client-info`,
responseType: 'json',
headers: {
'X-Token': token,
},
});

if (!result) {
throw new NotFoundError({
message:
'"token" (Monobank API token) is most likely invalid because we cannot find corresponding user.',
try {
const result = await axios({
method: 'GET',
url: `${hostname}/personal/client-info`,
responseType: 'json',
headers: {
'X-Token': token,
},
});
}

clientInfo = result.data;

await redisClient
.multi()
.set(redisToken, JSON.stringify(response))
.expire(redisToken, 60)
.exec();
if (!result) {
throw new NotFoundError({
message:
'"token" (Monobank API token) is most likely invalid because we cannot find corresponding user.',
});
}

clientInfo = result.data;

await redisClient
.multi()
.set(redisToken, JSON.stringify(response))
.expire(redisToken, 60)
.exec();
} catch (err) {
if (err?.response?.data?.errorDescription === "Unknown 'X-Token'") {
throw new ForbiddenError({
code: API_ERROR_CODES.monobankTokenInvalid,
message: 'Monobank rejected this token!',
});
} else {
throw new ForbiddenError({
code: API_ERROR_CODES.monobankTokenInvalid,
message: 'Token is invalid!',
});
}
}
} else {
clientInfo = JSON.parse(response);
}
Expand Down

0 comments on commit 6cb23b0

Please sign in to comment.