Skip to content

feat: error handler middleware #234

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Apr 7, 2025
7 changes: 5 additions & 2 deletions packages/wallet-service/src/api/addresses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { closeDbConnection, getDbConnection } from '@src/utils';
import { walletIdProxyHandler } from '@src/commons';
import middy from '@middy/core';
import cors from '@middy/http-cors';
import errorHandler from '@src/api/middlewares/errorHandler';

const mysql = getDbConnection();

Expand Down Expand Up @@ -104,7 +105,8 @@ export const checkMine: APIGatewayProxyHandler = middy(walletIdProxyHandler(asyn
addresses: addressBelongMap,
}),
};
})).use(cors());
})).use(cors())
.use(errorHandler());

/*
* Get the addresses of a wallet, allowing an index filter
Expand Down Expand Up @@ -169,4 +171,5 @@ export const get: APIGatewayProxyHandler = middy(
return response;
}),
).use(cors())
.use(warmupMiddleware());
.use(warmupMiddleware())
.use(errorHandler());
7 changes: 5 additions & 2 deletions packages/wallet-service/src/api/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import cors from '@middy/http-cors';
import createDefaultLogger from '@src/logger';
import { Logger } from 'winston';
import config from '@src/config';
import errorHandler from '@src/api/middlewares/errorHandler';

const EXPIRATION_TIME_IN_SECONDS = 1800;

Expand Down Expand Up @@ -153,7 +154,8 @@ export const tokenHandler: APIGatewayProxyHandler = middy(async (event) => {
statusCode: 200,
body: JSON.stringify({ success: true, token }),
};
}).use(cors());
}).use(cors())
.use(errorHandler());

/**
* Generates a aws policy document to allow/deny access to the resource
Expand Down Expand Up @@ -233,4 +235,5 @@ export const bearerAuthorizer: APIGatewayTokenAuthorizerHandler = middy(async (e
}

return _generatePolicy(walletId, 'Deny', event.methodArn, logger);
}).use(cors());
}).use(cors())
.use(errorHandler());
4 changes: 3 additions & 1 deletion packages/wallet-service/src/api/balances.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
import middy from '@middy/core';
import cors from '@middy/http-cors';
import Joi from 'joi';
import errorHandler from '@src/api/middlewares/errorHandler';

const mysql = getDbConnection();

Expand Down Expand Up @@ -81,4 +82,5 @@ export const get: APIGatewayProxyHandler = middy(walletIdProxyHandler(async (wal
body: JSON.stringify({ success: true, balances }),
};
})).use(cors())
.use(warmupMiddleware());
.use(warmupMiddleware())
.use(errorHandler());
1 change: 1 addition & 0 deletions packages/wallet-service/src/api/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export enum ApiError {
INVALID_TX_WEIGHT = 'invalid-tx-weight',
INVALID_SELECTION_ALGORITHM = 'invalid-selection-algorithm',
UNKNOWN_ERROR = 'unknown-error',
INTERNAL_SERVER_ERROR = 'internal-server-error',
INPUTS_NOT_FOUND = 'inputs-not-found',
INPUTS_ALREADY_USED = 'inputs-already-used',
INPUTS_NOT_IN_WALLET = 'inputs-not-in-wallet',
Expand Down
10 changes: 7 additions & 3 deletions packages/wallet-service/src/api/fullnodeProxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
GetTxByIdParams,
ParamValidationResult,
} from '@src/types';
import errorHandler from '@src/api/middlewares/errorHandler';

const mysql = getDbConnection();

Expand Down Expand Up @@ -70,7 +71,8 @@ export const getTransactionById: APIGatewayProxyHandler = middy(walletIdProxyHan
statusCode: 200,
body: JSON.stringify(transaction),
};
})).use(cors());
})).use(cors())
.use(errorHandler());

/*
* Get confirmation data for a tx from the fullnode
Expand All @@ -96,7 +98,8 @@ export const getConfirmationData: APIGatewayProxyHandler = middy(walletIdProxyHa
statusCode: 200,
body: JSON.stringify(confirmationData),
};
})).use(cors());
})).use(cors())
.use(errorHandler());

/*
* Makes graphviz queries on the fullnode
Expand Down Expand Up @@ -134,4 +137,5 @@ export const queryGraphvizNeighbours: APIGatewayProxyHandler = middy(
body: JSON.stringify(graphVizData),
};
}),
).use(cors());
).use(cors())
.use(errorHandler());
3 changes: 2 additions & 1 deletion packages/wallet-service/src/api/healthcheck.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { closeDbConnection, getDbConnection } from '@src/utils';
import { APIGatewayProxyHandler } from 'aws-lambda';
import { getRedisClient, ping } from '@src/redis';
import config from '@src/config';
import errorHandler from '@src/api/middlewares/errorHandler';

const mysql = getDbConnection();

Expand Down Expand Up @@ -141,4 +142,4 @@ export const getHealthcheck: APIGatewayProxyHandler = middy(async (event) => {
statusCode: response.getHttpStatusCode(),
body: response.toJson(),
};
});
}).use(errorHandler());
40 changes: 40 additions & 0 deletions packages/wallet-service/src/api/middlewares/errorHandler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* Copyright (c) Hathor Labs and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import middy from '@middy/core'
import { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda'
import createDefaultLogger from "@src/logger"
import { STATUS_CODE_TABLE } from '@src/api/utils';
import { ApiError } from '@src/api/errors';

const logger = createDefaultLogger();

const defaultResponse: APIGatewayProxyResult = { statusCode: STATUS_CODE_TABLE[ApiError.INTERNAL_SERVER_ERROR], body: ApiError.INTERNAL_SERVER_ERROR };

const errorHandler = (): middy.MiddlewareObj<APIGatewayProxyEvent, APIGatewayProxyResult> => {
const onError: middy.MiddlewareFn<APIGatewayProxyEvent, APIGatewayProxyResult> = async (request) => {
logger.error(`[${request.context?.functionName}] Unhandled error on ${request.event?.path}: ${request.error}`);

// Initialize response with default values if it hasn't been done yet.
request.response = request.response ?? {...defaultResponse};
// Force the status code to 500 since this is an unhandled error
request.response.statusCode = STATUS_CODE_TABLE[ApiError.INTERNAL_SERVER_ERROR];

// In production, we do not want to expose the error message to the user.
if (process.env.NODE_ENV === 'production') {
request.response.body = ApiError.INTERNAL_SERVER_ERROR;
return request.response;
}

request.response.body = request.error?.message || String(request.error);
return request.response;
}

return { onError };
}

export default errorHandler;
4 changes: 3 additions & 1 deletion packages/wallet-service/src/api/miners.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { closeDbConnection, getDbConnection } from '@src/utils';
import { Miner } from '@src/types';
import middy from '@middy/core';
import cors from '@middy/http-cors';
import errorHandler from '@src/api/middlewares/errorHandler';

const mysql = getDbConnection();

Expand All @@ -37,4 +38,5 @@ export const onMinersListRequest: APIGatewayProxyHandler = middy(async () => {
miners: minersList,
}),
};
}).use(cors());
}).use(cors())
.use(errorHandler());
4 changes: 3 additions & 1 deletion packages/wallet-service/src/api/newAddresses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { closeDbConnection, getDbConnection } from '@src/utils';
import { walletIdProxyHandler } from '@src/commons';
import middy from '@middy/core';
import cors from '@middy/http-cors';
import errorHandler from '@src/api/middlewares/errorHandler';

const mysql = getDbConnection();

Expand Down Expand Up @@ -47,4 +48,5 @@ export const get: APIGatewayProxyHandler = middy(walletIdProxyHandler(async (wal
body: JSON.stringify({ success: true, addresses }),
};
})).use(cors())
.use(warmupMiddleware());
.use(warmupMiddleware())
.use(errorHandler());
4 changes: 3 additions & 1 deletion packages/wallet-service/src/api/pushRegister.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import middy from '@middy/core';
import cors from '@middy/http-cors';
import Joi, { ValidationError } from 'joi';
import { PushRegister } from '@src/types';
import errorHandler from '@src/api/middlewares/errorHandler';

const mysql = getDbConnection();

Expand Down Expand Up @@ -80,4 +81,5 @@ export const register: APIGatewayProxyHandler = middy(walletIdProxyHandler(async
};
}))
.use(cors())
.use(warmupMiddleware());
.use(warmupMiddleware())
.use(errorHandler());
4 changes: 3 additions & 1 deletion packages/wallet-service/src/api/pushUnregister.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import middy from '@middy/core';
import cors from '@middy/http-cors';
import Joi, { ValidationError } from 'joi';
import { PushDelete } from '@src/types';
import errorHandler from '@src/api/middlewares/errorHandler';

const mysql = getDbConnection();

Expand Down Expand Up @@ -55,4 +56,5 @@ export const unregister: APIGatewayProxyHandler = middy(walletIdProxyHandler(asy
body: JSON.stringify({ success: true }),
};
}))
.use(cors());
.use(cors())
.use(errorHandler());
4 changes: 3 additions & 1 deletion packages/wallet-service/src/api/pushUpdate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import middy from '@middy/core';
import cors from '@middy/http-cors';
import Joi, { ValidationError } from 'joi';
import { PushUpdate } from '@src/types';
import errorHandler from '@src/api/middlewares/errorHandler';

const mysql = getDbConnection();

Expand Down Expand Up @@ -75,4 +76,5 @@ export const update: APIGatewayProxyHandler = middy(walletIdProxyHandler(async (
body: JSON.stringify({ success: true }),
};
}))
.use(cors());
.use(cors())
.use(errorHandler());
7 changes: 5 additions & 2 deletions packages/wallet-service/src/api/tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import Joi from 'joi';
import { constants } from '@hathor/wallet-lib';
import middy from '@middy/core';
import cors from '@middy/http-cors';
import errorHandler from '@src/api/middlewares/errorHandler';

const mysql = getDbConnection();

Expand All @@ -37,7 +38,8 @@ export const get = middy(walletIdProxyHandler(async (walletId) => {
}),
};
})).use(cors())
.use(warmupMiddleware());
.use(warmupMiddleware())
.use(errorHandler());

const getTokenDetailsParamsSchema = Joi.object({
token_id: txIdJoiValidator.required(),
Expand Down Expand Up @@ -112,4 +114,5 @@ export const getTokenDetails = middy(walletIdProxyHandler(async (walletId, event
}),
};
})).use(cors())
.use(warmupMiddleware());
.use(warmupMiddleware())
.use(errorHandler());
4 changes: 3 additions & 1 deletion packages/wallet-service/src/api/totalSupply.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import middy from '@middy/core';
import cors from '@middy/http-cors';
import hathorLib from '@hathor/wallet-lib';
import Joi from 'joi';
import errorHandler from '@src/api/middlewares/errorHandler';

const htrToken = hathorLib.constants.NATIVE_TOKEN_UID;
const mysql = getDbConnection();
Expand Down Expand Up @@ -61,4 +62,5 @@ export const onTotalSupplyRequest: APIGatewayProxyHandler = middy(async (event)
totalSupply,
}),
};
}).use(cors());
}).use(cors())
.use(errorHandler());
4 changes: 3 additions & 1 deletion packages/wallet-service/src/api/txById.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import middy from '@middy/core';
import cors from '@middy/http-cors';
import Joi, { ValidationError } from 'joi';
import { TxByIdRequest } from '@src/types';
import errorHandler from '@src/api/middlewares/errorHandler';

const mysql = getDbConnection();

Expand Down Expand Up @@ -59,4 +60,5 @@ export const get: APIGatewayProxyHandler = middy(walletIdProxyHandler(async (wal
};
}))
.use(cors())
.use(warmupMiddleware());
.use(warmupMiddleware())
.use(errorHandler());
7 changes: 5 additions & 2 deletions packages/wallet-service/src/api/txOutputs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { getDbConnection } from '@src/utils';
import { constants } from '@hathor/wallet-lib';
import middy from '@middy/core';
import cors from '@middy/http-cors';
import errorHandler from '@src/api/middlewares/errorHandler';

const mysql = getDbConnection();

Expand Down Expand Up @@ -92,7 +93,8 @@ export const getFilteredUtxos = middy(walletIdProxyHandler(async (walletId, even
}

return response;
})).use(cors());
})).use(cors())
.use(errorHandler());

/*
* Filter tx_outputs
Expand Down Expand Up @@ -131,7 +133,8 @@ export const getFilteredTxOutputs = middy(walletIdProxyHandler(async (walletId,
}

return _getFilteredTxOutputs(walletId, value);
})).use(cors());
})).use(cors())
.use(errorHandler());

const _getFilteredTxOutputs = async (walletId: string, filters: IFilterTxOutput) => {
const walletAddresses = await getWalletAddresses(mysql, walletId);
Expand Down
4 changes: 3 additions & 1 deletion packages/wallet-service/src/api/txProposalCreate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import cors from '@middy/http-cors';
import { constants, Network, Transaction, helpersUtils } from '@hathor/wallet-lib';
import { getFullnodeData } from '@src/nodeConfig';
import config from '@src/config';
import errorHandler from '@src/api/middlewares/errorHandler';

const mysql = getDbConnection();

Expand Down Expand Up @@ -143,7 +144,8 @@ export const create = middy(walletIdProxyHandler(async (walletId, event) => {
inputs: retInputs,
}),
};
})).use(cors());
})).use(cors())
.use(errorHandler());

/**
* Confirm that all inputs requested by the user have been fetched.
Expand Down
4 changes: 3 additions & 1 deletion packages/wallet-service/src/api/txProposalDestroy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { closeDbConnection, getDbConnection, getUnixTimestamp } from '@src/utils
import { closeDbAndGetError } from '@src/api/utils';
import middy from '@middy/core';
import cors from '@middy/http-cors';
import errorHandler from '@src/api/middlewares/errorHandler';

const mysql = getDbConnection();

Expand Down Expand Up @@ -67,4 +68,5 @@ export const destroy: APIGatewayProxyHandler = middy(walletIdProxyHandler(async
txProposalId,
}),
};
})).use(cors());
})).use(cors())
.use(errorHandler());
4 changes: 3 additions & 1 deletion packages/wallet-service/src/api/txProposalSend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { closeDbAndGetError } from '@src/api/utils';
import middy from '@middy/core';
import cors from '@middy/http-cors';
import config from '@src/config';
import errorHandler from '@src/api/middlewares/errorHandler';

const mysql = getDbConnection();

Expand Down Expand Up @@ -145,4 +146,5 @@ export const send: APIGatewayProxyHandler = middy(walletIdProxyHandler(async (wa
txHex,
});
}
})).use(cors());
})).use(cors())
.use(errorHandler());
4 changes: 3 additions & 1 deletion packages/wallet-service/src/api/txhistory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import middy from '@middy/core';
import cors from '@middy/http-cors';
import Joi from 'joi';
import config from '@src/config';
import errorHandler from '@src/api/middlewares/errorHandler';

const MAX_COUNT = config.txHistoryMaxCount;
const htrToken = hathorLib.constants.NATIVE_TOKEN_UID;
Expand Down Expand Up @@ -87,4 +88,5 @@ export const get = middy(walletIdProxyHandler(async (walletId, event) => {
body: JSON.stringify({ success: true, history, skip, count }),
};
})).use(cors())
.use(warmupMiddleware());
.use(warmupMiddleware())
.use(errorHandler());
1 change: 1 addition & 0 deletions packages/wallet-service/src/api/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export const STATUS_CODE_TABLE = {
[ApiError.INVALID_TX_WEIGHT]: 400,
[ApiError.INVALID_SELECTION_ALGORITHM]: 400,
[ApiError.UNKNOWN_ERROR]: 500,
[ApiError.INTERNAL_SERVER_ERROR]: 500,
[ApiError.INPUTS_NOT_FOUND]: 400,
[ApiError.INPUTS_ALREADY_USED]: 400,
[ApiError.INSUFFICIENT_FUNDS]: 400,
Expand Down
Loading