@dynatrace/react-native-plugin 2.279.1 → 2.279.3
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/README.md +5 -1
- package/ios/DynatraceRNBridge.m +24 -4
- package/lib/instrumentor/base/Application.js +3 -2
- package/lib/instrumentor/base/DynatraceInternal.js +0 -7
- package/lib/instrumentor/base/ErrorHandler.js +27 -3
- package/lib/instrumentor/base/Touchable.js +51 -21
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1274,8 +1274,12 @@ If you are struggling with a problem, submit a support ticket to Dynatrace (supp
|
|
|
1274
1274
|
<br/><br/>
|
|
1275
1275
|
## Changelog
|
|
1276
1276
|
|
|
1277
|
-
2.279.
|
|
1277
|
+
2.279.3
|
|
1278
|
+
* Updated iOS crash report sending strategy
|
|
1279
|
+
* Configuration printed on startup fixed
|
|
1278
1280
|
* Update Android (8.279.1.1002) & iOS Agent (8.279.1.1008)
|
|
1281
|
+
* Improved event handling for touchable instrumentation
|
|
1282
|
+
* Added logic for nested arrays when traversing touch event name
|
|
1279
1283
|
|
|
1280
1284
|
2.277.1
|
|
1281
1285
|
* Update Android (8.277.1.1003) & iOS Agent (8.277.1.1004)
|
package/ios/DynatraceRNBridge.m
CHANGED
|
@@ -181,6 +181,25 @@ RCT_EXPORT_METHOD(reportCrash:(NSString *)errorName errorReason:(NSString *)erro
|
|
|
181
181
|
}
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
+
RCT_EXPORT_METHOD(storeCrash:(NSString *)crashName reason:(NSString *)reason stacktrace:(NSString *)stacktrace platform:(NSString *) platform) {
|
|
185
|
+
if ([self shouldWorkOnIosWithPlatform: platform])
|
|
186
|
+
{
|
|
187
|
+
NSString* dirPath = [[[[NSFileManager defaultManager] URLsForDirectory:NSApplicationSupportDirectory inDomains:NSUserDomainMask] firstObject] path];
|
|
188
|
+
dirPath = [dirPath stringByAppendingPathComponent:@"DTXExternalCrashes"];
|
|
189
|
+
// Create the Application Support/DTXExternalCrashes directory if it does not exist
|
|
190
|
+
if (![[NSFileManager defaultManager] fileExistsAtPath:dirPath]) {
|
|
191
|
+
NSError *e;
|
|
192
|
+
[[NSFileManager defaultManager] createDirectoryAtPath:dirPath withIntermediateDirectories:YES attributes:nil error:&e];
|
|
193
|
+
NSAssert(e == nil, @"Couldn't create Application Support directory, %@", e.localizedDescription);
|
|
194
|
+
}
|
|
195
|
+
NSDictionary* crashDict = @{ @"crashName": crashName, @"reason": reason, @"stacktrace": stacktrace, @"technologyType": @"j" };
|
|
196
|
+
NSData* jsonData = [NSJSONSerialization dataWithJSONObject:crashDict options:NSJSONWritingPrettyPrinted error:nil];
|
|
197
|
+
NSString* crashJson= [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
|
198
|
+
// Store react native crash
|
|
199
|
+
[[NSFileManager defaultManager] createFileAtPath:[dirPath stringByAppendingPathComponent:@"RNCrash.txt"] contents:[crashJson dataUsingEncoding:NSUTF8StringEncoding] attributes:nil];
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
184
203
|
RCT_EXPORT_METHOD(reportErrorInAction:(nonnull NSString *)key errorName:(NSString *)errorName errorCode:(nonnull NSNumber *)errorCode platform: (NSString *) platform)
|
|
185
204
|
{
|
|
186
205
|
if ([self shouldWorkOnIosWithPlatform: platform])
|
|
@@ -237,6 +256,7 @@ RCT_EXPORT_METHOD(startWebRequestTiming:(NSString*) requestTag url:(NSString*) u
|
|
|
237
256
|
[timing startWebRequestTiming];
|
|
238
257
|
}
|
|
239
258
|
}
|
|
259
|
+
|
|
240
260
|
}
|
|
241
261
|
|
|
242
262
|
RCT_EXPORT_METHOD(stopWebRequestTiming:(NSString*) requestTag url:(NSString*)url responseCode:(nonnull NSNumber*) responseCode responseMessage:(NSString*)responseMessage)
|
|
@@ -420,7 +440,7 @@ RCT_EXPORT_METHOD(applyUserPrivacyOptions:(NSDictionary *) userPrivacyOptions pl
|
|
|
420
440
|
}
|
|
421
441
|
}
|
|
422
442
|
|
|
423
|
-
- (void)
|
|
443
|
+
- (void)newAction:(NSString *)name key:(nonnull NSString *)key parentAction:(DTXAction *)parentAction
|
|
424
444
|
{
|
|
425
445
|
DTXAction *action = [DTXAction integrateActionWithName:name];
|
|
426
446
|
|
|
@@ -430,7 +450,7 @@ RCT_EXPORT_METHOD(applyUserPrivacyOptions:(NSDictionary *) userPrivacyOptions pl
|
|
|
430
450
|
}
|
|
431
451
|
}
|
|
432
452
|
|
|
433
|
-
- (DTXAction *)
|
|
453
|
+
- (DTXAction *)getAction:(nonnull NSString *)key
|
|
434
454
|
{
|
|
435
455
|
return [actionDict objectForKey:key];
|
|
436
456
|
}
|
|
@@ -441,9 +461,9 @@ RCT_EXPORT_METHOD(applyUserPrivacyOptions:(NSDictionary *) userPrivacyOptions pl
|
|
|
441
461
|
return YES;
|
|
442
462
|
}
|
|
443
463
|
|
|
444
|
-
- (BOOL)
|
|
464
|
+
- (BOOL)shouldWorkOnIosWithPlatform: (NSString *) platform
|
|
445
465
|
{
|
|
446
466
|
return platform == nil || [platform isEqualToString:PlatformiOS] || [platform isEqualToString:@""];
|
|
447
467
|
}
|
|
448
468
|
|
|
449
|
-
@end
|
|
469
|
+
@end
|
|
@@ -7,8 +7,9 @@ const Logger_1 = require("./Logger");
|
|
|
7
7
|
exports.ApplicationHandler = {
|
|
8
8
|
startup: () => {
|
|
9
9
|
if (!ConfigurationHandler_1.ConfigurationHandler.isConfigurationAvailable()) {
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
const config = new ConfigurationBuilder_1.ConfigurationBuilder('', '').buildConfiguration();
|
|
11
|
+
ConfigurationHandler_1.ConfigurationHandler.setConfiguration(config);
|
|
12
|
+
Logger_1.Logger.logDebug('Configuration set: ' + JSON.stringify(config));
|
|
12
13
|
Logger_1.Logger.logInfo('Dynatrace React Native Plugin started!');
|
|
13
14
|
}
|
|
14
15
|
},
|
|
@@ -1,18 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.DynatraceInternal = void 0;
|
|
4
|
-
const StringUtils_1 = require("./util/StringUtils");
|
|
5
4
|
const DynatraceBridge_1 = require("./DynatraceBridge");
|
|
6
5
|
const Logger_1 = require("./Logger");
|
|
7
6
|
let counter = 0;
|
|
8
7
|
exports.DynatraceInternal = {
|
|
9
8
|
reportErrorFromHandler: (isFatal, errorName, reason, stacktrace, isCustomErrorHandlerSet, platform) => {
|
|
10
|
-
if (!StringUtils_1.StringUtils.isStringNullEmptyOrUndefined(reason)) {
|
|
11
|
-
const reasonNewLineIndex = reason.indexOf('\n');
|
|
12
|
-
if (reasonNewLineIndex !== -1) {
|
|
13
|
-
reason = reason.substring(0, reasonNewLineIndex);
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
9
|
Logger_1.Logger.logDebug(`Dynatrace reportErrorStacktrace(${isFatal}, ${errorName}, ${reason}, ${stacktrace})`);
|
|
17
10
|
if (isFatal) {
|
|
18
11
|
DynatraceBridge_1.DynatraceNative.reportCrash(errorName, reason, stacktrace, true, __DEV__ || isCustomErrorHandlerSet, platform);
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports._reportErrorToDynatrace = exports.isCustomErrorHandlerSet = exports.registerErrorHandler = void 0;
|
|
4
|
+
const ReactNative = require("react-native");
|
|
4
5
|
const DynatraceInternal_1 = require("./DynatraceInternal");
|
|
6
|
+
const DynatraceBridge_1 = require("./DynatraceBridge");
|
|
5
7
|
const Dynatrace_1 = require("./Dynatrace");
|
|
6
8
|
const StringUtils_1 = require("./util/StringUtils");
|
|
7
9
|
const Logger_1 = require("./Logger");
|
|
@@ -32,8 +34,14 @@ const _reportErrorToDynatrace = (exception, isFatal, oldHandler) => {
|
|
|
32
34
|
isFatal = false;
|
|
33
35
|
}
|
|
34
36
|
if (exception.stack != null) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
+
if (ReactNative.Platform.OS === 'ios') {
|
|
38
|
+
DynatraceBridge_1.DynatraceNative.storeCrash(String(exception.name), adjustedReason(exception.message), exception.stack);
|
|
39
|
+
Logger_1.Logger.logDebug(`ErrorHandler storeCrash(${exception}, ${isFatal})`);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
DynatraceInternal_1.DynatraceInternal.reportErrorFromHandler(isFatal, String(exception.name), adjustedReason(exception.message), exception.stack, _isCustomErrorHandlerSet);
|
|
43
|
+
Logger_1.Logger.logDebug(`ErrorHandler _reportErrorToDynatrace(${exception}, ${isFatal})`);
|
|
44
|
+
}
|
|
37
45
|
}
|
|
38
46
|
else {
|
|
39
47
|
Dynatrace_1.Dynatrace.reportError(String(exception.name) + ': ' + exception.message, -1);
|
|
@@ -46,8 +54,24 @@ const _reportErrorToDynatrace = (exception, isFatal, oldHandler) => {
|
|
|
46
54
|
Logger_1.Logger.logDebug(`ErrorHandler _reportErrorToDynatrace(${exception})`);
|
|
47
55
|
}
|
|
48
56
|
if (oldHandler !== undefined) {
|
|
49
|
-
|
|
57
|
+
if (ReactNative.Platform.OS === 'ios') {
|
|
58
|
+
setTimeout(() => {
|
|
59
|
+
oldHandler(exception, isFatal);
|
|
60
|
+
}, 200);
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
oldHandler(exception, isFatal);
|
|
64
|
+
}
|
|
50
65
|
}
|
|
51
66
|
};
|
|
52
67
|
exports._reportErrorToDynatrace = _reportErrorToDynatrace;
|
|
68
|
+
const adjustedReason = (reason) => {
|
|
69
|
+
if (!StringUtils_1.StringUtils.isStringNullEmptyOrUndefined(reason)) {
|
|
70
|
+
const reasonNewLineIndex = reason.indexOf('\n');
|
|
71
|
+
if (reasonNewLineIndex !== -1) {
|
|
72
|
+
reason = reason.substring(0, reasonNewLineIndex);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return reason;
|
|
76
|
+
};
|
|
53
77
|
const isExceptionAnError = (exception) => exception.message !== undefined;
|
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
exports.TouchableHelper = void 0;
|
|
13
4
|
const ConfigurationHandler_1 = require("./configuration/ConfigurationHandler");
|
|
@@ -18,17 +9,17 @@ const TouchableHelper = (Dynatrace, Logger) => ({
|
|
|
18
9
|
: props.onPress;
|
|
19
10
|
const nameOfAction = this._findActionName(props, children);
|
|
20
11
|
const isButton = this._isPropsButton(props);
|
|
21
|
-
return (event) =>
|
|
12
|
+
return (event) => {
|
|
22
13
|
if (nameOfAction == null) {
|
|
23
14
|
Logger.logDebug('TouchableHelper: Skipping creation of action as no name was found!');
|
|
24
15
|
if (origFunction != null) {
|
|
25
|
-
|
|
16
|
+
return origFunction(event);
|
|
26
17
|
}
|
|
27
18
|
}
|
|
28
19
|
else if (!ConfigurationHandler_1.ConfigurationHandler.isConfigurationAvailable()) {
|
|
29
20
|
Logger.logInfo('TouchableHelper: React Native plugin has not been started yet! Touch will not be reported!');
|
|
30
21
|
if (origFunction != null) {
|
|
31
|
-
|
|
22
|
+
return origFunction(event);
|
|
32
23
|
}
|
|
33
24
|
}
|
|
34
25
|
else {
|
|
@@ -38,11 +29,34 @@ const TouchableHelper = (Dynatrace, Logger) => ({
|
|
|
38
29
|
}
|
|
39
30
|
const action = Dynatrace.enterAutoAction(`Touch on ${finalNameOfAction}`);
|
|
40
31
|
if (origFunction != null) {
|
|
41
|
-
|
|
32
|
+
let isError = true;
|
|
33
|
+
try {
|
|
34
|
+
const promise = origFunction(event);
|
|
35
|
+
if (promise != null && typeof promise.then === 'function'
|
|
36
|
+
&& typeof promise.catch === 'function') {
|
|
37
|
+
promise.then(() => {
|
|
38
|
+
action.leaveAction();
|
|
39
|
+
});
|
|
40
|
+
promise.catch(() => {
|
|
41
|
+
action.leaveAction();
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
action.leaveAction();
|
|
46
|
+
}
|
|
47
|
+
isError = false;
|
|
48
|
+
}
|
|
49
|
+
finally {
|
|
50
|
+
if (isError) {
|
|
51
|
+
action.leaveAction();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
action.leaveAction();
|
|
42
57
|
}
|
|
43
|
-
action.leaveAction();
|
|
44
58
|
}
|
|
45
|
-
}
|
|
59
|
+
};
|
|
46
60
|
},
|
|
47
61
|
_findActionName(props, children) {
|
|
48
62
|
if (this._isDynatraceProperties(props)) {
|
|
@@ -54,14 +68,24 @@ const TouchableHelper = (Dynatrace, Logger) => ({
|
|
|
54
68
|
else if (props.accessibilityLabel != null) {
|
|
55
69
|
return props.accessibilityLabel;
|
|
56
70
|
}
|
|
57
|
-
else if (children != null &&
|
|
58
|
-
children.length === 1 &&
|
|
59
|
-
|
|
60
|
-
|
|
71
|
+
else if (children != null && children.length > 0) {
|
|
72
|
+
if (children.length === 1 &&
|
|
73
|
+
typeof children[0] === 'string') {
|
|
74
|
+
return children[0];
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
return this._walkChildrenToFindText(children);
|
|
78
|
+
}
|
|
61
79
|
}
|
|
62
|
-
else {
|
|
63
|
-
|
|
80
|
+
else if (props.children != null) {
|
|
81
|
+
if (typeof props.children === 'string') {
|
|
82
|
+
return props.children;
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
return this._walkChildrenToFindText(props.children);
|
|
86
|
+
}
|
|
64
87
|
}
|
|
88
|
+
return null;
|
|
65
89
|
},
|
|
66
90
|
_isPropsButton: (props) => props.title != null,
|
|
67
91
|
_isImageButton: (props) => props.source != null,
|
|
@@ -100,6 +124,12 @@ const TouchableHelper = (Dynatrace, Logger) => ({
|
|
|
100
124
|
return name;
|
|
101
125
|
}
|
|
102
126
|
}
|
|
127
|
+
else if (typeof child === 'string') {
|
|
128
|
+
return child;
|
|
129
|
+
}
|
|
130
|
+
else if (Array.isArray(child)) {
|
|
131
|
+
return this._walkChildrenToFindText(child);
|
|
132
|
+
}
|
|
103
133
|
}
|
|
104
134
|
return null;
|
|
105
135
|
}
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"@dynatrace/react-native-plugin","version":"2.279.
|
|
1
|
+
{"name":"@dynatrace/react-native-plugin","version":"2.279.3","description":"This plugin gives you the ability to use the Dynatrace Mobile agent in your react native application.","main":"index.js","types":"typings/react-native-dynatrace.d.ts","bin":{"instrumentDynatrace":"scripts/Instrument.js","configDynatrace":"scripts/CheckConfig.js"},"keywords":["react-native","dynatrace","mobile","android","ios","performance","monitoring"],"rnpm":{"plugin":"./command/command.js"},"scripts":{"uninstall":"node ./scripts/Uninstall.js","test":"jest --runInBand","test:debug":"node --inspect-brk ./node_modules/jest/bin/jest.js --runInBand","tsc":"tsc","tsc:prod":"tsc -p tsconfig.release.json","lint":"eslint --cache src/**/*.ts --ignore-pattern .gitignore","lint:spec":"eslint --cache tests/**/*.ts --cache-file tests/.eslintcache --ignore-pattern .gitignore --fix"},"jest":{"preset":"react-native","moduleDirectories":["node_modules"],"unmockedModulePathPatterns":["node_modules"],"modulePathIgnorePatterns":["<rootDir>/src","<rootDir>/tests/commandTestTmp","node_modules/react-native/local-cli"],"transform":{"^.+\\.(ts|tsx)$":"ts-jest"},"testPathIgnorePatterns":["<rootDir>/src","<rootDir>/tests/commandTestTmp"],"transformIgnorePatterns":["node_modules/(?!(@react-native|react-native)/)"],"setupFiles":["<rootDir>/tests/setup/setup.js"],"testResultsProcessor":"jest-junit","testRegex":["(/__tests__/.*|(\\.|/)(Test|spec))\\.[jt]sx?$"]},"jest-junit":{"suiteName":"jest tests","outputDirectory":".","outputName":"junit.xml","uniqueOutputName":"true","ancestorSeparator":" › ","usePathForSuiteName":"true"},"author":"Dynatrace","license":"SEE LICENSE IN LICENSE.md","dependencies":{"@babel/runtime":"^7.23.5","jscodeshift":"^0.15.1","plist":"^3.1.0","proxy-polyfill":"^0.3.2","semver":"^7.5.4"},"homepage":"https://www.dynatrace.com/","peerDependencies":{"@babel/parser":">=7.4.4","@react-native-picker/picker":">=1.0.0","react":">=16.8.0","react-native":">=0.59.0"},"devDependencies":{"@babel/cli":"^7.22.9","@babel/plugin-proposal-class-properties":"^7.8.3","@babel/plugin-proposal-nullish-coalescing-operator":"^7.8.3","@babel/plugin-proposal-optional-chaining":"^7.8.3","@babel/plugin-transform-flow-strip-types":"^7.8.3","@babel/plugin-transform-runtime":"^7.12.1","@babel/preset-env":"^7.4.4","@babel/preset-react":"^7.8.3","@testing-library/react-native":"^7.0.2","@types/jest":"^26.0.19","@types/jscodeshift":"^0.11.6","@types/libxmljs":"^0.18.3","@types/node":"^18.17.12","@types/plist":"^3.0.2","@types/react-native":"^0.63.32","@types/semver":"^7.5.0","@types/shelljs":"^0.8.8","@types/uglify-js":"^3.17.1","@typescript-eslint/eslint-plugin":"^5.16.0","@typescript-eslint/parser":"^5.16.0","compressing":"^1.5.1","eslint":"^8.45.0","eslint-config-prettier":"^8.5.0","eslint-plugin-import":"^2.26.0","eslint-plugin-jsdoc":"^39.1.0","eslint-plugin-prefer-arrow":"^1.2.3","eslint-plugin-unicorn":"^42.0.0","jest":"24.9.0","jest-each":"^28.1.3","jest-junit":"^14.0.0","jest-mock":"^28.1.3","npm-check-updates":"^16.10.12","prettier":"^2.6.1","shelljs":"^0.8.5","ts-jest":"24.3.0","ts-mockito":"^2.6.1","typescript":"^4.7.4","uglify-js":"^3.17.4","react-native":"0.71.3","react":"18.2.0","react-test-renderer":"18.2.0"},"files":["command/command.js","command/util/*","command/interface/*","android/build.gradle","android/src/main/**/*","ios/**/*","files/*","lib/instrumentor/base/*.js","lib/instrumentor/base/model/*.js","lib/instrumentor/base/configuration/*.js","lib/instrumentor/base/configuration/interface/*.js","lib/instrumentor/base/interface/*.js","lib/instrumentor/base/util/*.js","lib/instrumentor/model/*.js","lib/instrumentor/parser/*.js","lib/instrumentor/DynatraceInstrumentation.js","lib/*.js","lib/community/*.js","lib/community/gesture-handler/*.js","lib/react-navigation/*.js","lib/react-native/*.js","lib/react/*.js","lib/metro/*.js","lib/util/*.js","react-native.config.js","react-native-dynatrace.js","react-native-dynatrace.podspec","README.md","LICENSE.md","scripts/*","scripts/api/*","scripts/core/*","scripts/api/model/*","scripts/util/*","typings/*","package.json","jsx-runtime.js"]}
|