Skip to content

Commit bac81c8

Browse files
skarimjaysylvester
authored andcommitted
fixes for properties of undefined errors
1 parent fd95627 commit bac81c8

File tree

4 files changed

+28
-15
lines changed

4 files changed

+28
-15
lines changed

src/analyze/ruby/extractors.js

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,38 +14,44 @@ const { getValueType } = require('./types');
1414
function extractEventName(node, source) {
1515
if (source === 'segment' || source === 'rudderstack') {
1616
// Both Segment and Rudderstack use the same format
17-
const params = node.arguments_.arguments_[0].elements;
17+
const params = node.arguments_?.arguments_?.[0]?.elements;
18+
if (!params || !Array.isArray(params)) {
19+
return null;
20+
}
1821
const eventProperty = params.find(param => param?.key?.unescaped?.value === 'event');
1922
return eventProperty?.value?.unescaped?.value || null;
2023
}
2124

2225
if (source === 'mixpanel') {
2326
// Mixpanel Ruby SDK format: tracker.track('distinct_id', 'event_name', {...})
24-
const args = node.arguments_.arguments_;
27+
const args = node.arguments_?.arguments_;
2528
if (args && args.length > 1 && args[1]?.unescaped?.value) {
2629
return args[1].unescaped.value;
2730
}
2831
}
2932

3033
if (source === 'posthog') {
3134
// PostHog Ruby SDK format: posthog.capture({distinct_id: '...', event: '...', properties: {...}})
32-
const hashArg = node.arguments_.arguments_[0];
33-
if (hashArg && hashArg.elements) {
35+
const hashArg = node.arguments_?.arguments_?.[0];
36+
if (hashArg && hashArg.elements && Array.isArray(hashArg.elements)) {
3437
const eventProperty = hashArg.elements.find(elem => elem?.key?.unescaped?.value === 'event');
3538
return eventProperty?.value?.unescaped?.value || null;
3639
}
3740
}
3841

3942
if (source === 'snowplow') {
4043
// Snowplow Ruby SDK: tracker.track_struct_event(category: '...', action: '...', ...)
41-
const params = node.arguments_.arguments_[0].elements;
44+
const params = node.arguments_?.arguments_?.[0]?.elements;
45+
if (!params || !Array.isArray(params)) {
46+
return null;
47+
}
4248
const actionProperty = params.find(param => param?.key?.unescaped?.value === 'action');
4349
return actionProperty?.value?.unescaped?.value || null;
4450
}
4551

4652
if (source === 'custom') {
4753
// Custom function format: customFunction('event_name', {...})
48-
const args = node.arguments_.arguments_;
54+
const args = node.arguments_?.arguments_;
4955
if (args && args.length > 0 && args[0]?.unescaped?.value) {
5056
return args[0].unescaped.value;
5157
}
@@ -65,7 +71,10 @@ async function extractProperties(node, source) {
6571

6672
if (source === 'segment' || source === 'rudderstack') {
6773
// Both Segment and Rudderstack use the same format
68-
const params = node.arguments_.arguments_[0].elements;
74+
const params = node.arguments_?.arguments_?.[0]?.elements;
75+
if (!params || !Array.isArray(params)) {
76+
return null;
77+
}
6978
const properties = {};
7079

7180
// Process all top-level fields except 'event'
@@ -108,7 +117,7 @@ async function extractProperties(node, source) {
108117

109118
if (source === 'mixpanel') {
110119
// Mixpanel Ruby SDK: tracker.track('distinct_id', 'event_name', {properties})
111-
const args = node.arguments_.arguments_;
120+
const args = node.arguments_?.arguments_;
112121
const properties = {};
113122

114123
// Add distinct_id as property (even if it's a variable)
@@ -129,10 +138,10 @@ async function extractProperties(node, source) {
129138

130139
if (source === 'posthog') {
131140
// PostHog Ruby SDK: posthog.capture({distinct_id: '...', event: '...', properties: {...}})
132-
const hashArg = node.arguments_.arguments_[0];
141+
const hashArg = node.arguments_?.arguments_?.[0];
133142
const properties = {};
134143

135-
if (hashArg && hashArg.elements) {
144+
if (hashArg && hashArg.elements && Array.isArray(hashArg.elements)) {
136145
// Extract distinct_id if present
137146
const distinctIdProperty = hashArg.elements.find(elem => elem?.key?.unescaped?.value === 'distinct_id');
138147
if (distinctIdProperty?.value) {
@@ -154,7 +163,10 @@ async function extractProperties(node, source) {
154163

155164
if (source === 'snowplow') {
156165
// Snowplow Ruby SDK: tracker.track_struct_event(category: '...', action: '...', ...)
157-
const params = node.arguments_.arguments_[0].elements;
166+
const params = node.arguments_?.arguments_?.[0]?.elements;
167+
if (!params || !Array.isArray(params)) {
168+
return null;
169+
}
158170
const properties = {};
159171

160172
// Extract all struct event parameters except 'action' (which is used as the event name)
@@ -172,7 +184,7 @@ async function extractProperties(node, source) {
172184

173185
if (source === 'custom') {
174186
// Custom function format: customFunction('event_name', {properties})
175-
const args = node.arguments_.arguments_;
187+
const args = node.arguments_?.arguments_;
176188
if (args && args.length > 1 && args[1] instanceof HashNode) {
177189
return await extractHashProperties(args[1]);
178190
}

src/analyze/typescript/detectors/analytics-source.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,8 @@ function detectMemberBasedProvider(node) {
8484
return 'unknown';
8585
}
8686

87-
const objectName = node.expression.expression.escapedText;
88-
const methodName = node.expression.name.escapedText;
87+
const objectName = node.expression.expression?.escapedText;
88+
const methodName = node.expression.name?.escapedText;
8989

9090
if (!objectName || !methodName) {
9191
return 'unknown';

src/analyze/typescript/extractors/property-extractor.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,7 @@ function resolveTypeSchema(checker, typeString) {
350350
* @returns {string|null} Literal type or null
351351
*/
352352
function getLiteralType(node) {
353+
if (!node) return null;
353354
if (ts.isStringLiteral(node)) return 'string';
354355
if (ts.isNumericLiteral(node)) return 'number';
355356
if (node.kind === ts.SyntaxKind.TrueKeyword || node.kind === ts.SyntaxKind.FalseKeyword) return 'boolean';

src/analyze/typescript/utils/function-finder.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ function findParentFunctionName(node) {
9393
parent.initializer &&
9494
ts.isCallExpression(parent.initializer) &&
9595
ts.isIdentifier(parent.initializer.expression) &&
96-
REACT_HOOKS.has(parent.initializer.expression.escapedText)
96+
isReactHookCall(parent.initializer)
9797
) {
9898
return `${parent.initializer.expression.escapedText}(${parent.name.escapedText})`;
9999
}

0 commit comments

Comments
 (0)