autotel-subscribers 27.0.1 → 28.0.0
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.
- package/dist/factories.cjs +178 -3
- package/dist/factories.cjs.map +1 -1
- package/dist/factories.js +177 -3
- package/dist/factories.js.map +1 -1
- package/dist/index.cjs +178 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +177 -3
- package/dist/index.js.map +1 -1
- package/dist/posthog.cjs +181 -3
- package/dist/posthog.cjs.map +1 -1
- package/dist/posthog.d.cts +25 -0
- package/dist/posthog.d.ts +25 -0
- package/dist/posthog.js +177 -3
- package/dist/posthog.js.map +1 -1
- package/package.json +5 -4
- package/src/posthog-capture-exception.test.ts +146 -0
- package/src/posthog-error-formatter.test.ts +152 -0
- package/src/posthog-error-formatter.ts +113 -0
- package/src/posthog-redaction.test.ts +143 -0
- package/src/posthog.ts +144 -2
package/dist/factories.cjs
CHANGED
|
@@ -12,6 +12,7 @@ var https = require('https');
|
|
|
12
12
|
var buffer = require('buffer');
|
|
13
13
|
var util = require('util');
|
|
14
14
|
var crypto2 = require('crypto');
|
|
15
|
+
var slowRedact = require('slow-redact');
|
|
15
16
|
|
|
16
17
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
17
18
|
|
|
@@ -40,6 +41,7 @@ var http__namespace = /*#__PURE__*/_interopNamespace(http);
|
|
|
40
41
|
var https__namespace = /*#__PURE__*/_interopNamespace(https);
|
|
41
42
|
var util__namespace = /*#__PURE__*/_interopNamespace(util);
|
|
42
43
|
var crypto2__namespace = /*#__PURE__*/_interopNamespace(crypto2);
|
|
44
|
+
var slowRedact__default = /*#__PURE__*/_interopDefault(slowRedact);
|
|
43
45
|
|
|
44
46
|
var __create = Object.create;
|
|
45
47
|
var __defProp = Object.defineProperty;
|
|
@@ -13855,7 +13857,70 @@ var EventSubscriber = class {
|
|
|
13855
13857
|
}
|
|
13856
13858
|
};
|
|
13857
13859
|
|
|
13858
|
-
// src/posthog.ts
|
|
13860
|
+
// src/posthog-error-formatter.ts
|
|
13861
|
+
var MAX_CAUSE_DEPTH = 5;
|
|
13862
|
+
function formatExceptionForPostHog(exceptionList, platform = "web:javascript", redactor) {
|
|
13863
|
+
return {
|
|
13864
|
+
$exception_list: exceptionList.map((ex) => ({
|
|
13865
|
+
type: ex.type,
|
|
13866
|
+
value: redactor ? redactor(ex.value) : ex.value,
|
|
13867
|
+
mechanism: ex.mechanism,
|
|
13868
|
+
stacktrace: {
|
|
13869
|
+
frames: (ex.stacktrace?.frames || []).map((frame) => ({
|
|
13870
|
+
...frame,
|
|
13871
|
+
abs_path: frame.abs_path && redactor ? redactor(frame.abs_path) : frame.abs_path,
|
|
13872
|
+
platform
|
|
13873
|
+
}))
|
|
13874
|
+
}
|
|
13875
|
+
}))
|
|
13876
|
+
};
|
|
13877
|
+
}
|
|
13878
|
+
function errorToExceptionList(input, redactor) {
|
|
13879
|
+
const error = input instanceof Error ? input : new Error(
|
|
13880
|
+
input === null || input === void 0 ? "Unknown error" : String(input)
|
|
13881
|
+
);
|
|
13882
|
+
const records = [];
|
|
13883
|
+
let current = error;
|
|
13884
|
+
let depth = 0;
|
|
13885
|
+
while (current && depth < MAX_CAUSE_DEPTH) {
|
|
13886
|
+
const value = current.message || "Unknown error";
|
|
13887
|
+
const frames = current.stack ? parseStackBasic(current.stack) : void 0;
|
|
13888
|
+
records.push({
|
|
13889
|
+
type: current.name || "Error",
|
|
13890
|
+
value: redactor ? redactor(value) : value,
|
|
13891
|
+
mechanism: { type: "manual", handled: true },
|
|
13892
|
+
stacktrace: frames ? {
|
|
13893
|
+
frames: redactor ? frames.map((f) => ({
|
|
13894
|
+
...f,
|
|
13895
|
+
abs_path: f.abs_path ? redactor(f.abs_path) : f.abs_path
|
|
13896
|
+
})) : frames
|
|
13897
|
+
} : void 0
|
|
13898
|
+
});
|
|
13899
|
+
current = current.cause instanceof Error ? current.cause : void 0;
|
|
13900
|
+
depth++;
|
|
13901
|
+
}
|
|
13902
|
+
return records.toReversed();
|
|
13903
|
+
}
|
|
13904
|
+
function parseStackBasic(stack) {
|
|
13905
|
+
const lines = stack.split("\n");
|
|
13906
|
+
const frames = [];
|
|
13907
|
+
const re = /^\s*at\s+(?:(.+?)\s+\()?(.+?):(\d+):(\d+)\)?$/;
|
|
13908
|
+
for (const line of lines) {
|
|
13909
|
+
const match = line.trim().match(re);
|
|
13910
|
+
if (match) {
|
|
13911
|
+
const [, fn, absPath, lineStr, colStr] = match;
|
|
13912
|
+
frames.push({
|
|
13913
|
+
function: fn || void 0,
|
|
13914
|
+
abs_path: absPath,
|
|
13915
|
+
filename: absPath.split("/").pop() || absPath,
|
|
13916
|
+
lineno: Number.parseInt(lineStr, 10),
|
|
13917
|
+
colno: Number.parseInt(colStr, 10),
|
|
13918
|
+
in_app: !absPath.includes("node_modules")
|
|
13919
|
+
});
|
|
13920
|
+
}
|
|
13921
|
+
}
|
|
13922
|
+
return frames;
|
|
13923
|
+
}
|
|
13859
13924
|
var PostHogSubscriber = class extends EventSubscriber {
|
|
13860
13925
|
name = "PostHogSubscriber";
|
|
13861
13926
|
version = "2.0.0";
|
|
@@ -13864,6 +13929,8 @@ var PostHogSubscriber = class extends EventSubscriber {
|
|
|
13864
13929
|
initPromise = null;
|
|
13865
13930
|
/** True when using browser's window.posthog (different API signature) */
|
|
13866
13931
|
isBrowserClient = false;
|
|
13932
|
+
pathRedactor = null;
|
|
13933
|
+
stringRedactor = null;
|
|
13867
13934
|
constructor(config) {
|
|
13868
13935
|
super();
|
|
13869
13936
|
if (config.serverless) {
|
|
@@ -13885,6 +13952,15 @@ var PostHogSubscriber = class extends EventSubscriber {
|
|
|
13885
13952
|
filterUndefinedValues: true,
|
|
13886
13953
|
...config
|
|
13887
13954
|
};
|
|
13955
|
+
if (this.config.redactPaths && this.config.redactPaths.length > 0) {
|
|
13956
|
+
this.pathRedactor = slowRedact__default.default({
|
|
13957
|
+
paths: this.config.redactPaths,
|
|
13958
|
+
serialize: false
|
|
13959
|
+
});
|
|
13960
|
+
}
|
|
13961
|
+
if (this.config.stringRedactor) {
|
|
13962
|
+
this.stringRedactor = this.config.stringRedactor;
|
|
13963
|
+
}
|
|
13888
13964
|
if (this.enabled) {
|
|
13889
13965
|
this.initPromise = this.initialize();
|
|
13890
13966
|
}
|
|
@@ -13944,6 +14020,50 @@ var PostHogSubscriber = class extends EventSubscriber {
|
|
|
13944
14020
|
extractDistinctId(attributes) {
|
|
13945
14021
|
return attributes?.userId || attributes?.user_id || "anonymous";
|
|
13946
14022
|
}
|
|
14023
|
+
redactProperties(properties) {
|
|
14024
|
+
let result = properties;
|
|
14025
|
+
if (this.pathRedactor) {
|
|
14026
|
+
result = this.pathRedactor(properties);
|
|
14027
|
+
}
|
|
14028
|
+
if (this.stringRedactor) {
|
|
14029
|
+
result = this.redactStringValues(result);
|
|
14030
|
+
}
|
|
14031
|
+
return result;
|
|
14032
|
+
}
|
|
14033
|
+
redactStringValues(obj) {
|
|
14034
|
+
const result = {};
|
|
14035
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
14036
|
+
if (typeof value === "string") {
|
|
14037
|
+
result[key] = this.stringRedactor(value);
|
|
14038
|
+
} else if (Array.isArray(value)) {
|
|
14039
|
+
result[key] = this.redactArray(value);
|
|
14040
|
+
} else if (value !== null && typeof value === "object") {
|
|
14041
|
+
result[key] = this.redactStringValues(value);
|
|
14042
|
+
} else {
|
|
14043
|
+
result[key] = value;
|
|
14044
|
+
}
|
|
14045
|
+
}
|
|
14046
|
+
return result;
|
|
14047
|
+
}
|
|
14048
|
+
redactArray(arr) {
|
|
14049
|
+
return arr.map((item) => {
|
|
14050
|
+
if (typeof item === "string") {
|
|
14051
|
+
return this.stringRedactor(item);
|
|
14052
|
+
} else if (Array.isArray(item)) {
|
|
14053
|
+
return this.redactArray(item);
|
|
14054
|
+
} else if (item !== null && typeof item === "object") {
|
|
14055
|
+
return this.redactStringValues(item);
|
|
14056
|
+
}
|
|
14057
|
+
return item;
|
|
14058
|
+
});
|
|
14059
|
+
}
|
|
14060
|
+
/**
|
|
14061
|
+
* Set the string redactor. Called by autotel init() when attributeRedactor is configured.
|
|
14062
|
+
* Can also be called manually.
|
|
14063
|
+
*/
|
|
14064
|
+
setStringRedactor(redactor) {
|
|
14065
|
+
this.stringRedactor = redactor;
|
|
14066
|
+
}
|
|
13947
14067
|
/**
|
|
13948
14068
|
* Send payload to PostHog
|
|
13949
14069
|
*
|
|
@@ -13995,14 +14115,39 @@ var PostHogSubscriber = class extends EventSubscriber {
|
|
|
13995
14115
|
properties.$linked_trace_ids = payload.autotel.linked_trace_ids;
|
|
13996
14116
|
}
|
|
13997
14117
|
}
|
|
14118
|
+
const redactedProperties = this.redactProperties(properties);
|
|
14119
|
+
if (payload.attributes?.["exception.list"]) {
|
|
14120
|
+
try {
|
|
14121
|
+
const exceptionList = JSON.parse(payload.attributes["exception.list"]);
|
|
14122
|
+
const formatted = formatExceptionForPostHog(
|
|
14123
|
+
exceptionList,
|
|
14124
|
+
void 0,
|
|
14125
|
+
this.stringRedactor ?? void 0
|
|
14126
|
+
);
|
|
14127
|
+
const exceptionProperties = {
|
|
14128
|
+
...redactedProperties,
|
|
14129
|
+
...formatted
|
|
14130
|
+
};
|
|
14131
|
+
if (this.isBrowserClient) {
|
|
14132
|
+
this.posthog?.capture("$exception", exceptionProperties);
|
|
14133
|
+
} else {
|
|
14134
|
+
this.posthog?.capture({
|
|
14135
|
+
distinctId: this.extractDistinctId(filteredAttributes),
|
|
14136
|
+
event: "$exception",
|
|
14137
|
+
properties: exceptionProperties
|
|
14138
|
+
});
|
|
14139
|
+
}
|
|
14140
|
+
} catch {
|
|
14141
|
+
}
|
|
14142
|
+
}
|
|
13998
14143
|
const distinctId = this.extractDistinctId(filteredAttributes);
|
|
13999
14144
|
if (this.isBrowserClient) {
|
|
14000
|
-
this.posthog?.capture(payload.name,
|
|
14145
|
+
this.posthog?.capture(payload.name, redactedProperties);
|
|
14001
14146
|
} else {
|
|
14002
14147
|
const capturePayload = {
|
|
14003
14148
|
distinctId,
|
|
14004
14149
|
event: payload.name,
|
|
14005
|
-
properties
|
|
14150
|
+
properties: redactedProperties
|
|
14006
14151
|
};
|
|
14007
14152
|
if (filteredAttributes?.groups) {
|
|
14008
14153
|
capturePayload.groups = filteredAttributes.groups;
|
|
@@ -14211,6 +14356,36 @@ var PostHogSubscriber = class extends EventSubscriber {
|
|
|
14211
14356
|
}
|
|
14212
14357
|
await this.trackEvent(name, eventAttributes);
|
|
14213
14358
|
}
|
|
14359
|
+
/**
|
|
14360
|
+
* Capture an exception and send to PostHog error tracking.
|
|
14361
|
+
*
|
|
14362
|
+
* If using browser client (window.posthog), delegates to its captureException.
|
|
14363
|
+
* Otherwise, formats and sends via posthog-node capture API.
|
|
14364
|
+
*/
|
|
14365
|
+
async captureException(error, options) {
|
|
14366
|
+
if (!this.enabled) return;
|
|
14367
|
+
await this.ensureInitialized();
|
|
14368
|
+
try {
|
|
14369
|
+
if (this.isBrowserClient) {
|
|
14370
|
+
const browserProps = options?.additionalProperties ? this.redactProperties(options.additionalProperties) : void 0;
|
|
14371
|
+
this.posthog?.captureException?.(error, browserProps);
|
|
14372
|
+
return;
|
|
14373
|
+
}
|
|
14374
|
+
const exceptionList = errorToExceptionList(error, this.stringRedactor ?? void 0);
|
|
14375
|
+
const formatted = formatExceptionForPostHog(exceptionList, "node:javascript", this.stringRedactor ?? void 0);
|
|
14376
|
+
const properties = {
|
|
14377
|
+
...formatted,
|
|
14378
|
+
...options?.additionalProperties
|
|
14379
|
+
};
|
|
14380
|
+
this.posthog?.capture({
|
|
14381
|
+
distinctId: options?.distinctId || "anonymous",
|
|
14382
|
+
event: "$exception",
|
|
14383
|
+
properties: this.redactProperties(properties)
|
|
14384
|
+
});
|
|
14385
|
+
} catch (error_) {
|
|
14386
|
+
this.config.onError?.(error_);
|
|
14387
|
+
}
|
|
14388
|
+
}
|
|
14214
14389
|
/**
|
|
14215
14390
|
* Flush pending events and clean up resources
|
|
14216
14391
|
*/
|