@mhubcloud/tms_core 3.8.0-beta.6 → 3.8.0-beta.7

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.
Files changed (2) hide show
  1. package/dist/index.js +100 -71
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -53,6 +53,7 @@ var import_service_bus = require("@azure/service-bus");
53
53
  // src/utils/utils.ts
54
54
  var utils_exports = {};
55
55
  __export(utils_exports, {
56
+ DestinationError: () => DestinationError,
56
57
  EventPublisherBase: () => EventPublisherBase,
57
58
  encodeEmail: () => encodeEmail,
58
59
  extractAdCode: () => extractAdCode,
@@ -78,9 +79,13 @@ var appInsights = __toESM(require("applicationinsights"));
78
79
  var import_redis = require("redis");
79
80
  var client;
80
81
  async function getRedisClient() {
82
+ const redisUrl = process.env["RedisUrl"];
83
+ if (!redisUrl) {
84
+ return null;
85
+ }
81
86
  if (!client) {
82
87
  client = (0, import_redis.createClient)({
83
- url: `rediss://${process.env["RedisUrl"]}`,
88
+ url: `rediss://${redisUrl}`,
84
89
  password: process.env["RedisPassword"],
85
90
  socket: { tls: true }
86
91
  });
@@ -118,14 +123,39 @@ var EventPublisherBase = class {
118
123
  };
119
124
  async function logRedisEvent(key) {
120
125
  const redis = await getRedisClient();
121
- if (!redis) return;
122
- await redis.hIncrBy(key, "count", 1);
123
- await redis.expire(key, 660);
126
+ if (!redis) {
127
+ return;
128
+ }
129
+ await redis.multi().hIncrBy(key, "count", 1).expire(key, 660).exec();
124
130
  }
125
- function logAggregatedMetric({ prefix, name, dimensions }) {
131
+ var DestinationError = class _DestinationError extends Error {
132
+ metricType;
133
+ constructor(message, metricType) {
134
+ super(message);
135
+ this.name = "DestinationError";
136
+ this.metricType = metricType;
137
+ }
138
+ static fromResponse(message, status) {
139
+ const metricType = status === 408 || status === 429 || status >= 500 ? "PlatformError" : "RequestError";
140
+ return new _DestinationError(message, metricType);
141
+ }
142
+ static fromNetworkFailure(error) {
143
+ const message = error instanceof Error ? error.message : String(error);
144
+ return new _DestinationError(message, "PlatformError");
145
+ }
146
+ };
147
+ function logAggregatedMetric({
148
+ prefix,
149
+ name,
150
+ dimensions
151
+ }) {
126
152
  const windowStart = Math.floor(Date.now() / 6e4) * 6e4;
127
153
  const key = dimensions ? `${prefix}:${windowStart}:${dimensions}:${name}` : `${prefix}:${windowStart}:${name}`;
128
- logRedisEvent(key);
154
+ void logRedisEvent(key).catch((error) => {
155
+ if (error instanceof Error) {
156
+ logException(new Error(`Metric log error: ${error.message}`));
157
+ }
158
+ });
129
159
  }
130
160
  function logMetric(name, value, properties) {
131
161
  aiClient?.trackMetric({
@@ -144,13 +174,15 @@ function logMessage(level, message, properties) {
144
174
  });
145
175
  }
146
176
  function logEvent(publisher2, event, region, status, payload, id) {
147
- if (!process.env["DisableMetrics"]) {
148
- const metricRegion = process.env["DisableMetricRegionLogging"] ? "default" : region;
149
- const name = status >= 200 && status < 400 ? "DispatchSuccess" : "DispatchFailure";
150
- logAggregatedMetric({ prefix: "events", dimensions: `${metricRegion}:${publisher2}:${event}`, name });
177
+ if (!process.env.DisableMetrics && status >= 200 && status < 400) {
178
+ const metricRegion = process.env.DisableMetricRegionLogging ? "default" : region;
179
+ logAggregatedMetric({
180
+ prefix: "events",
181
+ dimensions: `${metricRegion}:${publisher2}:${event}`,
182
+ name: "Dispatch"
183
+ });
151
184
  }
152
- ;
153
- if (!process.env["DisableTraces"]) {
185
+ if (!process.env.DisableTraces) {
154
186
  let properties = {
155
187
  publisher: publisher2,
156
188
  event,
@@ -163,18 +195,21 @@ function logEvent(publisher2, event, region, status, payload, id) {
163
195
  properties = removeUndefined(properties);
164
196
  logMessage(1, message, properties);
165
197
  }
166
- ;
167
198
  }
168
- function logException(exception, publisher2) {
169
- if (!process.env["DisableMetrics"]) {
170
- const message = exception.message.split(".")[0]?.substring(0, 100)?.replace(/:/g, "") ?? "Error";
171
- logAggregatedMetric({ prefix: "errors", dimensions: `${publisher2 ?? "Other"}:${exception.name}`, name: message });
199
+ function logException(exception, publisher2, errorType = "InternalError") {
200
+ if (!process.env.DisableMetrics) {
201
+ logAggregatedMetric({
202
+ prefix: "errors",
203
+ dimensions: publisher2 ?? "Other",
204
+ name: errorType
205
+ });
172
206
  }
173
- ;
174
- if (!process.env["DisableTraces"]) {
175
- aiClient?.trackException({ exception });
207
+ if (!process.env.DisableTraces) {
208
+ aiClient?.trackException({
209
+ exception,
210
+ properties: { publisher: publisher2, errorType }
211
+ });
176
212
  }
177
- ;
178
213
  }
179
214
  function logMilestone(name) {
180
215
  logAggregatedMetric({ prefix: "milestones", name });
@@ -318,29 +353,21 @@ async function handlePlatformRequest({
318
353
  // eslint-disable-next-line @typescript-eslint/naming-convention
319
354
  headers: { ...requestOptions.headers }
320
355
  };
321
- let rawPlatformResponse;
322
- try {
323
- rawPlatformResponse = await fetch(fullUrl, fetchRequestOptions);
324
- } catch (e) {
325
- logEvent(
326
- source,
327
- event.event,
328
- event.region,
329
- 0,
330
- requestOptions.method === "POST" ? JSON.stringify(requestOptions.body) : query,
331
- event.id
332
- );
333
- throw e;
356
+ const rawPlatformResponse = await fetch(fullUrl, fetchRequestOptions);
357
+ if (process.env.PUBLISHER_TESTURL) {
358
+ await handleTestRequest({
359
+ fetchRequestOptions,
360
+ fullUrl,
361
+ query,
362
+ rawPlatformResponse
363
+ });
334
364
  }
335
- if (rawPlatformResponse) {
336
- if (process.env.PUBLISHER_TESTURL) {
337
- await handleTestRequest({
338
- fetchRequestOptions,
339
- fullUrl,
340
- query,
341
- rawPlatformResponse
342
- });
343
- }
365
+ if (!rawPlatformResponse.ok) {
366
+ throw DestinationError.fromResponse(
367
+ `HTTP Error code: ${rawPlatformResponse.status}, event: ${event.event}, region: ${event.region}, body: ${await rawPlatformResponse.text()}`,
368
+ rawPlatformResponse.status
369
+ );
370
+ } else {
344
371
  logEvent(
345
372
  source,
346
373
  event.event,
@@ -349,11 +376,6 @@ async function handlePlatformRequest({
349
376
  requestOptions.method === "POST" ? JSON.stringify(requestOptions.body) : query,
350
377
  event.id
351
378
  );
352
- if (!rawPlatformResponse.ok) {
353
- throw new Error(
354
- `HTTP Error code: ${rawPlatformResponse.status}, event: ${event.event}, region: ${event.region}, body: ${await rawPlatformResponse.text()}`
355
- );
356
- }
357
379
  }
358
380
  }
359
381
  async function handleTestRequest(params) {
@@ -381,7 +403,7 @@ function formatError(error) {
381
403
  if (error instanceof Error) {
382
404
  formattedError = error;
383
405
  if (error.cause) {
384
- formattedError.message = `${error.message} Cause: ${error.cause.toString()}`;
406
+ formattedError.message = `${error.message} Cause: ${String(error.cause)}`;
385
407
  } else {
386
408
  formattedError.message = error.message;
387
409
  }
@@ -638,13 +660,14 @@ async function defaultPublisher(azureFunctionContext, serviceBusMessage, source,
638
660
  if (result.status === "rejected") {
639
661
  if (result.reason instanceof Error) {
640
662
  const formattedError = formatError(result.reason);
641
- logException(new Error(formattedError.message), source);
663
+ const errorType = result.reason instanceof DestinationError ? result.reason.metricType : "InternalError";
664
+ logException(formattedError, source, errorType);
642
665
  throw formattedError;
643
666
  } else {
644
667
  const formattedError = formatError(
645
668
  typeof result.reason === "object" ? JSON.stringify(result.reason) : result.reason
646
669
  );
647
- logException(new Error(formattedError.message), source);
670
+ logException(formattedError, source, "InternalError");
648
671
  throw formattedError;
649
672
  }
650
673
  }
@@ -900,17 +923,17 @@ var googleAds = {
900
923
  error = responseJson.error.message;
901
924
  } else {
902
925
  status = 200;
926
+ logEvent(
927
+ this.source,
928
+ event.event,
929
+ event.region,
930
+ status,
931
+ requestOptions.body,
932
+ event.id
933
+ );
903
934
  }
904
- logEvent(
905
- this.source,
906
- event.event,
907
- event.region,
908
- status,
909
- requestOptions.body,
910
- event.id
911
- );
912
935
  if (error) {
913
- throw new Error(error);
936
+ throw DestinationError.fromResponse(error, response.status);
914
937
  }
915
938
  },
916
939
  async getToken(config) {
@@ -941,7 +964,10 @@ var googleAds = {
941
964
  }
942
965
  );
943
966
  if (!tokenResponse.ok) {
944
- throw new Error("Access token fetch failed");
967
+ throw DestinationError.fromResponse(
968
+ "Access token fetch failed",
969
+ tokenResponse.status
970
+ );
945
971
  }
946
972
  const parsedTokenResponse = await tokenResponse.json();
947
973
  const createdAt = Date.now();
@@ -1059,17 +1085,17 @@ var microsoftAds = {
1059
1085
  error = message;
1060
1086
  } else {
1061
1087
  status = 200;
1088
+ logEvent(
1089
+ this.source,
1090
+ event.event,
1091
+ event.region,
1092
+ status,
1093
+ requestOptions.body,
1094
+ event.id
1095
+ );
1062
1096
  }
1063
- logEvent(
1064
- this.source,
1065
- event.event,
1066
- event.region,
1067
- status,
1068
- requestOptions.body,
1069
- event.id
1070
- );
1071
1097
  if (error) {
1072
- throw new Error(error);
1098
+ throw DestinationError.fromResponse(error, response.status);
1073
1099
  }
1074
1100
  } else {
1075
1101
  throw new Error("Invalid config for platform " + this.source);
@@ -1100,7 +1126,10 @@ var microsoftAds = {
1100
1126
  }
1101
1127
  );
1102
1128
  if (!tokenResponse.ok) {
1103
- throw new Error("Access token fetch failed");
1129
+ throw DestinationError.fromResponse(
1130
+ "Access token fetch failed",
1131
+ tokenResponse.status
1132
+ );
1104
1133
  }
1105
1134
  const parsedTokenResponse = await tokenResponse.json();
1106
1135
  const createdAt = Date.now();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mhubcloud/tms_core",
3
- "version": "3.8.0-beta.6",
3
+ "version": "3.8.0-beta.7",
4
4
  "description": "Core function for mHub Cloud TMS publishers",
5
5
  "homepage": "https://mhubcloud.com/",
6
6
  "license": "Apache 2.0",