@provis/provis-common-be-module 3.0.4 → 3.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3 @@
1
+ import IErrorContext from '../interface/error.context.interface';
2
+ export declare function buildErrorKey(err: any, env: string, service: string): string;
3
+ export default function notifyError(err: any, ctx: IErrorContext): void;
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildErrorKey = buildErrorKey;
4
+ exports.default = notifyError;
5
+ const axios_1 = require("axios");
6
+ const THROTTLE_MS = 60000;
7
+ const THROTTLE_MAX_KEYS = 1000;
8
+ const WEBHOOK_TIMEOUT_MS = 3000;
9
+ const MESSAGE_MAX_LENGTH = 1000;
10
+ const STACK_MAX_LENGTH = 3000;
11
+ // Throttle per key per proses, supaya badai error tidak membanjiri n8n
12
+ const lastSent = new Map();
13
+ function buildErrorKey(err, env, service) {
14
+ var _a, _b, _c;
15
+ // Frame pertama yang menunjuk ke kode aplikasi (bukan library / internal Node)
16
+ const frame = String((_a = err === null || err === void 0 ? void 0 : err.stack) !== null && _a !== void 0 ? _a : '').split('\n').slice(1)
17
+ .find((line) => !line.includes('node_modules') && !line.includes('node:internal') && /:\d+:\d+/.test(line));
18
+ // Ambil basename + nomor baris, berlaku untuk path Linux maupun Windows
19
+ const location = frame === null || frame === void 0 ? void 0 : frame.match(/([^/\\(\s]+):(\d+):\d+\)?\s*$/);
20
+ const fileLine = location ? `${location[1]}:${location[2]}` : 'unknown';
21
+ const code = (_c = (_b = err === null || err === void 0 ? void 0 : err.code) !== null && _b !== void 0 ? _b : err === null || err === void 0 ? void 0 : err.name) !== null && _c !== void 0 ? _c : 500;
22
+ return `${env}-${service}-${fileLine}-${code}`;
23
+ }
24
+ // Message TypeORM/driver bisa memuat SQL dan nilai baris (data nasabah/polis), jadi jangan dikirim mentah
25
+ function safeMessage(err) {
26
+ var _a, _b;
27
+ if ((err === null || err === void 0 ? void 0 : err.name) === 'QueryFailedError')
28
+ return `${err.name} ${(_a = err.code) !== null && _a !== void 0 ? _a : ''}`.trim();
29
+ return String((_b = err === null || err === void 0 ? void 0 : err.message) !== null && _b !== void 0 ? _b : err).slice(0, MESSAGE_MAX_LENGTH);
30
+ }
31
+ function isThrottled(errorKey) {
32
+ var _a;
33
+ const now = Date.now();
34
+ if (now - ((_a = lastSent.get(errorKey)) !== null && _a !== void 0 ? _a : 0) < THROTTLE_MS)
35
+ return true;
36
+ if (lastSent.size >= THROTTLE_MAX_KEYS)
37
+ lastSent.clear();
38
+ lastSent.set(errorKey, now);
39
+ return false;
40
+ }
41
+ function notifyError(err, ctx) {
42
+ var _a, _b;
43
+ const webhookUrl = process.env.ERROR_WEBHOOK_URL;
44
+ const webhookSecret = process.env.ERROR_WEBHOOK_SECRET;
45
+ if (process.env.ERROR_NOTIFIER_ENABLED !== 'true' || !webhookUrl)
46
+ return;
47
+ try {
48
+ const errorKey = buildErrorKey(err, ctx.env, ctx.service);
49
+ if (isThrottled(errorKey))
50
+ return;
51
+ axios_1.default.post(webhookUrl, {
52
+ errorKey,
53
+ env: ctx.env,
54
+ service: ctx.service,
55
+ message: safeMessage(err),
56
+ stack: String((_a = err === null || err === void 0 ? void 0 : err.stack) !== null && _a !== void 0 ? _a : '').slice(0, STACK_MAX_LENGTH),
57
+ method: ctx.method,
58
+ // Query string bisa berisi data sensitif, selalu dibuang
59
+ endpoint: (_b = ctx.endpoint) === null || _b === void 0 ? void 0 : _b.split('?')[0],
60
+ correlationId: ctx.correlationId,
61
+ timestamp: new Date().toLocaleString('id-ID', { timeZone: 'Asia/Jakarta' }),
62
+ }, {
63
+ timeout: WEBHOOK_TIMEOUT_MS,
64
+ // Secret opsional; axios 0.21 menolak header bernilai undefined, jadi hanya dikirim jika di-set
65
+ headers: webhookSecret ? { 'X-Webhook-Secret': webhookSecret } : {},
66
+ }).catch((e) => console.log(`[error-notifier] ${e === null || e === void 0 ? void 0 : e.message}`));
67
+ }
68
+ catch (e) {
69
+ console.log(`[error-notifier] ${e === null || e === void 0 ? void 0 : e.message}`);
70
+ }
71
+ }
@@ -29,4 +29,5 @@ import alphaNumericCleansing from "./alphaNumericCleansing";
29
29
  import coretaxDppCalculate from "./coretaxDppCalculate";
30
30
  import getEmailContent, { initEmailTemplates } from "./getEmailContent";
31
31
  import { AMOUNT_SCALE, toUnits, fromUnits, sumUnits } from "./decimalAmount";
32
- export { addDateTime, amountDescription, axiosGet, axiosPost, axiosPut, compareDiffObj, convertCurrencySymbol, convertDateTimeFormat, convertObjToNumber, convertToCurrency, filterObj, generateRelationId, getCurrentDate, getDiffValue, getObjByKeys, loop, loopBackward, searchValue, readExcel, generateHashString, mergeObj, combineObj, calculateByType, getCargoType, getHeaderUser, setHeaderUser, alphaNumericCleansing, findObjectByParams, coretaxDppCalculate, getEmailContent, initEmailTemplates, AMOUNT_SCALE, toUnits, fromUnits, sumUnits, };
32
+ import notifyError, { buildErrorKey } from "./errorNotifier";
33
+ export { addDateTime, amountDescription, axiosGet, axiosPost, axiosPut, compareDiffObj, convertCurrencySymbol, convertDateTimeFormat, convertObjToNumber, convertToCurrency, filterObj, generateRelationId, getCurrentDate, getDiffValue, getObjByKeys, loop, loopBackward, searchValue, readExcel, generateHashString, mergeObj, combineObj, calculateByType, getCargoType, getHeaderUser, setHeaderUser, alphaNumericCleansing, findObjectByParams, coretaxDppCalculate, getEmailContent, initEmailTemplates, AMOUNT_SCALE, toUnits, fromUnits, sumUnits, notifyError, buildErrorKey, };
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.sumUnits = exports.fromUnits = exports.toUnits = exports.AMOUNT_SCALE = exports.initEmailTemplates = exports.getEmailContent = exports.coretaxDppCalculate = exports.findObjectByParams = exports.alphaNumericCleansing = exports.setHeaderUser = exports.getHeaderUser = exports.getCargoType = exports.calculateByType = exports.combineObj = exports.mergeObj = exports.generateHashString = exports.readExcel = exports.searchValue = exports.loopBackward = exports.loop = exports.getObjByKeys = exports.getDiffValue = exports.getCurrentDate = exports.generateRelationId = exports.filterObj = exports.convertToCurrency = exports.convertObjToNumber = exports.convertDateTimeFormat = exports.convertCurrencySymbol = exports.compareDiffObj = exports.axiosPut = exports.axiosPost = exports.axiosGet = exports.amountDescription = exports.addDateTime = void 0;
3
+ exports.buildErrorKey = exports.notifyError = exports.sumUnits = exports.fromUnits = exports.toUnits = exports.AMOUNT_SCALE = exports.initEmailTemplates = exports.getEmailContent = exports.coretaxDppCalculate = exports.findObjectByParams = exports.alphaNumericCleansing = exports.setHeaderUser = exports.getHeaderUser = exports.getCargoType = exports.calculateByType = exports.combineObj = exports.mergeObj = exports.generateHashString = exports.readExcel = exports.searchValue = exports.loopBackward = exports.loop = exports.getObjByKeys = exports.getDiffValue = exports.getCurrentDate = exports.generateRelationId = exports.filterObj = exports.convertToCurrency = exports.convertObjToNumber = exports.convertDateTimeFormat = exports.convertCurrencySymbol = exports.compareDiffObj = exports.axiosPut = exports.axiosPost = exports.axiosGet = exports.amountDescription = exports.addDateTime = void 0;
4
4
  const addDateTime_1 = require("./addDateTime");
5
5
  exports.addDateTime = addDateTime_1.default;
6
6
  const amountDescription_1 = require("./amountDescription");
@@ -67,3 +67,6 @@ Object.defineProperty(exports, "AMOUNT_SCALE", { enumerable: true, get: function
67
67
  Object.defineProperty(exports, "toUnits", { enumerable: true, get: function () { return decimalAmount_1.toUnits; } });
68
68
  Object.defineProperty(exports, "fromUnits", { enumerable: true, get: function () { return decimalAmount_1.fromUnits; } });
69
69
  Object.defineProperty(exports, "sumUnits", { enumerable: true, get: function () { return decimalAmount_1.sumUnits; } });
70
+ const errorNotifier_1 = require("./errorNotifier");
71
+ exports.notifyError = errorNotifier_1.default;
72
+ Object.defineProperty(exports, "buildErrorKey", { enumerable: true, get: function () { return errorNotifier_1.buildErrorKey; } });
@@ -0,0 +1,7 @@
1
+ export default interface IErrorContext {
2
+ env: string;
3
+ service: string;
4
+ method?: string;
5
+ endpoint?: string;
6
+ correlationId?: string;
7
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "@provis/provis-common-be-module",
3
- "version": "3.0.4",
3
+ "version": "3.0.5",
4
4
  "description": "This common module for Provis internal backend use lib",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
7
7
  "build": "tsc && npm run copy-json",
8
8
  "copy-json": "find src -name '*.json' -exec sh -c 'mkdir -p dist/$(dirname {} | sed s/^src//) && cp {} dist/$(echo {} | sed s/^src//)' \\;",
9
- "pub": "npm run build && npm publish --access=public"
9
+ "pub": "npm run build && npm publish --access=public",
10
+ "test": "tsc && node --test test/*.test.js"
10
11
  },
11
12
  "keywords": [],
12
13
  "author": "Provis Team",