故障排除
排查和解决 React Native SDK 的常见问题。
自 2024 年 5 月 1 日起,Apple 要求所有提交到 App Store 的应用程序提供他们使用的隐私相关 API 列表,包括使用这些 API 的原因。如果您收到 Apple 的邮件,内容为 "ITMS-91053: Missing API declaration",则您的应用程序不符合要求。要解决此问题,请按照我们的 Apple 隐私清单 指南操作。
iOS 15 引入了预热功能,影响了 Sentry SDK 的计算。此问题在 SDK 版本 4.1.1 中已修复。请更新到此版本或更高版本。
更多详情,请参阅 iOS SDK 的故障排除页面。
由于 React Native 依赖项的问题,未处理的 Promise 拒绝可能不会被 Sentry 正确捕获。如果 Promise 拒绝处理程序未正确附加,我们的 SDK 可能会发出警告:
WARN: 未处理的 Promise 拒绝可能不会被 Sentry 捕获。请参阅我们的故障排除文档了解如何解决此问题。
否则,我们会通知您处理程序已附加:
[Sentry] 未处理的 Promise 拒绝将被 Sentry 捕获。
默认情况下,我们会修补全局 Promise
实例,以确保它与 React Native 使用的版本完全匹配。
如果您使用修补全局 Promise
实例的 polyfill 库,请确保在调用 Sentry.init
之后运行该 polyfill。
import allSettled from "promise.allsettled";
Sentry.init({
dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
});
// Any Promise polyfilling must occur AFTER Sentry.init
// This step globally patches Promise.
allSettled.shim();
// Separate core-js example
import "core-js/stable/promise/all-settled";
您的 linter 可能会在此处抛出一些错误,但此步骤是必要的。
您可以通过在 Sentry.init
或 ReactNativeErrorHandlers
集成中传递 patchGlobalPromise: false
来禁用全局 Promise 修补。请注意,如果您禁用我们的自动修补,为了确保未处理的拒绝仍然被捕获,您需要 手动强制包解析。
如果您没有禁用 自动修补,则不需要执行以下步骤。您需要确保使用的 promise
版本与 React Native 使用的版本完全匹配。
- 检查您使用的
react-native
版本中promise
的版本。您可以通过进入node_modules/react-native/package.json
并查看其中的版本来完成此操作。例如,我们发现它使用的是^8.0.3
:
node_modules/react-native/package.json
{
"dependencies": {
// ...
"promise": "^8.0.3"
}
}
- 在 您的
package.json
文件中添加一个与react-native
相同版本的包解析,这将强制使用该版本。然后,您需要运行yarn install
或npm install
以使用刚刚添加的包解析。
package.json
{
"resolutions": {
"promise": "^8.0.3"
}
}
包解析目前仅由 yarn
支持。如果您使用 npm
,可以使用第三方包 npm-force-resolutions 来实现这一点。
- 如果修复成功,我们的 SDK 将不再显示上述警告,并指示 Promise 拒绝将被捕获。
当事件中存在源映射问题时,通常会在 sentry.io 的问题详情页面顶部显示一个错误对话框:
处理此事件时出现问题:未找到源代码
解决此问题的常见方法包括:
- 检查事件中的
release
和dist
是否已设置,通过在init
调用中设置它们来实现。设置版本。 - 检查源映射是否正确上传,并且与事件的
release
和dist
值完全匹配。它们必须匹配才能正确上传源映射。 - 如果您设置了自定义的
release
和dist
,请确认您手动上传了源映射,因为我们的自动源映射上传脚本不会检测自定义值。 - 确保堆栈跟踪中的包名称与源映射中的名称完全匹配。例如,如果堆栈帧显示
app:///index.bundle
,则源映射文件必须分别命名为index.bundle
和index.bundle.map
。 - 检查是否通过覆盖、过滤或设置
defaultIntegrations: false
禁用了默认的RewriteFrames
集成。
尽管构建脚本通常会自动处理这些情况,但在使用 Hermes 引擎时,您可能需要执行一些额外的步骤。您可以参考此处的指南。
您的应用程序可能为每个支持的平台(如 iOS 和 Android)使用不同的 Bundle。为了将正确的 Bundle 和源映射与每个平台关联,您需要为每个平台使用唯一的 release/dist
组合。一种简单的方法是在 dist
值中包含平台名称。
如果您使用的是较旧版本的 SDK(版本 3.2.12
或更低)或 sentry-cli
(版本 1.71.0
或更低),请尝试在构建脚本中向 Sentry CLI 命令传递 --force-foreground
参数:
# ...
../node_modules/@sentry/cli/bin/sentry-cli react-native xcode \
../node_modules/react-native/scripts/react-native-xcode.sh --force-foreground
如果您的发布健康统计数据被错误地归因于错误的发布版本,请确认您在 init
调用中传递了 release
和 dist
。
如果您使用 Code Push,请检查是否未使用 setRelease
和 setDist
,因为它们会破坏发布健康统计。您可以在 CodePush 指南 中了解更多。
在生产环境中打包时,React Native 会混淆类和函数名称以减少 Bundle 大小。这意味着在触摸事件面包屑或 Profiler 跨度中您将无法获得完整的原始组件名称。
解决此问题的一种方法是在您希望跟踪触摸事件的所有组件上设置 displayName
,或将 name
属性传递给 Profiler 组件。此外,您还可以通过在 metro.config.js
中设置以下选项来配置 Metro bundler 不混淆函数名称:
metro.config.js
module.exports = {
transformer: {
minifierConfig: {
keep_classnames: true, // Preserve class names
keep_fnames: true, // Preserve function names
mangle: {
keep_classnames: true, // Preserve class names
keep_fnames: true, // Preserve function names
},
},
},
};
此设置适用于 所有 类和函数名称 — 不仅限于 React 组件 — 并且可能会增加您的 JS Bundle 大小。
如果 Android NDK 事件缺少上下文(如面包屑、用户等),您需要启用 Scope 同步 功能。
如果使用 nvm 或 Volta,Xcode 可能无法找到默认的 node 二进制文件。要解决此问题,请将 node
二进制文件路径添加到 Bundle React Native code and images 构建阶段,如下所示:
export NODE_BINARY=path/to/your/node
# ... rest of the script
或者在终端中执行此命令:ln -s $(which node) /usr/local/bin/node
。
如果您使用的是 React Navigation 5
且不再收到事务,可能是由于 此 bug。升级到 React Navigation 6
应该可以解决此问题,但如果问题仍然存在,请在我们的 仓库 中提交问题。
如果您在使用 RAM Bundles 时在 sentry.io 上遇到行号不匹配的问题,这是由于 Metro 工具中的 bug。
Xcode 集成从 CFBundleVersion
读取 dist
,但 Xcode Cloud 构建使用 CI_BUILD_NUMBER
变量。请将以下代码添加到 Bundle React Native code and images
构建阶段,以启用正确的源映射上传。
export SENTRY_DIST=$CI_BUILD_NUMBER
如果您在应用程序构建过程中看到类似 Unknown receiver 'SwiftDescriptor'
或 Use of undeclared identifier 'SentryLog'
的错误,这可能是由于 APPLICATION_EXTENSION_API_ONLY
的冲突引起的。默认情况下,Sentry Cocoapod 配置为 APPLICATION_EXTENSION_API_ONLY=YES
,但某些 post_install
脚本可能更改了此设置。要解决此错误,请在 Podfile
中添加以下内容:
ios/Podfile
post_install do |installer|
react_native_post_install(
installer,
config[:reactNativePath],
:mac_catalyst_enabled => false,
)
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
if target.name == 'Sentry'
config.build_settings['APPLICATION_EXTENSION_API_ONLY'] = 'YES'
else
# configuration for other targets
end
end
end
end
如果您启用了 Gradle 的 org.gradle.configureondemand
功能,您需要进行一次干净的构建,或者禁用此功能以在每次构建时上传源映射。
要禁用此功能,请在 gradle.properties
文件中设置 org.gradle.configureondemand=false
或移除该设置,因为其默认值是禁用的。
要安装较旧版本的 @sentry/react-native
,您需要在安装命令中指定版本。同样,您需要使用兼容的 @sentry/wizard
,如下脚本所示。
yarn add @sentry/react-native@4
npx @sentry/wizard@1 -i reactNative -p ios android
npx pod-install
在构建应用程序之前,请检查 android/app/build.gradle
是否已使用以下 Gradle 集成进行修补:
apply from: "../../node_modules/@sentry/react-native/sentry.gradle"
即使这在 Android 上可以正常工作,它仍然会在 iOS 的 Bundle React Native code and images
构建步骤阶段失败。要解决此问题,请在 ios/$projectName.xcodeproj/project.pbxproj
文件中回滚修补的 shellScript
(其中 $projectName
是您的项目名称)。然后搜索构建步骤阶段 Bundle React Native code and images
并修补 shellScript
。
Old:
shellScript = "set -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n";
New:
shellScript = "set -e\nexport SENTRY_PROPERTIES=sentry.properties\nexport EXTRA_PACKAGER_ARGS=\"--sourcemap-output $DERIVED_FILE_DIR/main.jsbundle.map\"\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\nSENTRY_CLI_PATH=\"../node_modules/@sentry/cli/bin/sentry-cli\"\n/bin/sh -c \"$WITH_ENVIRONMENT \\\"$SENTRY_CLI_PATH react-native xcode $REACT_NATIVE_XCODE\\\"\"";
如果您的构建因 react-native.config.js
中的过时字段而失败,请更新位于 node_modules/@sentry/react-native/react-native.config.js
的配置文件。这对于 React Native v0.69 是必需的。目前,更新版本只会显示警告。
Old:
module.exports = {
dependency: {
platforms: {
ios: {
sharedLibraries: ["libz"],
},
android: {
packageInstance: "new RNSentryPackage()",
},
},
hooks: {
postlink:
"node node_modules/@sentry/wizard/dist/bin.js -i reactNative -p ios android",
postunlink:
"node node_modules/@sentry/wizard/dist/bin.js -i reactNative -p ios android --uninstall",
},
},
};
New:
module.exports = {
dependency: {
platforms: {
ios: {},
android: {
packageInstance: "new RNSentryPackage()",
},
},
},
};
React Native 0.60.3 的工具意外移动了源映射文件,导致 Sentry Gradle 插件失败。此问题在版本 0.60.4 中已修复。更多详细信息,请参阅 问题。
如果您使用的是 SDK v5.10.0 或更早版本,请在 Xcode 中使用以下构建阶段。如果您使用的是 SDK v5.11.0 或更新版本,请阅读当前的 手动设置指南。
Bundle React Native code and images
export SENTRY_PROPERTIES=sentry.properties
export EXTRA_PACKAGER_ARGS="--sourcemap-output $DERIVED_FILE_DIR/main.jsbundle.map"
set -e
# RN 0.69+
WITH_ENVIRONMENT="../node_modules/react-native/scripts/xcode/with-environment.sh"
REACT_NATIVE_XCODE="../node_modules/react-native/scripts/react-native-xcode.sh"
SENTRY_CLI="../node_modules/@sentry/cli/bin/sentry-cli"
/bin/sh -c "$WITH_ENVIRONMENT \"$SENTRY_CLI react-native xcode $REACT_NATIVE_XCODE\""
# RN 0.46 – 0.68
# ../node_modules/@sentry/cli/bin/sentry-cli react-native xcode \
# ../node_modules/react-native/scripts/react-native-xcode.sh
# All versions
/bin/sh ../node_modules/@sentry/react-native/scripts/collect-modules.sh
以及用于上传原生调试符号的构建阶段。
Upload Debug Symbols to Sentry
export SENTRY_PROPERTIES=sentry.properties
[[ $SENTRY_INCLUDE_NATIVE_SOURCES == "true" ]] && INCLUDE_SOURCES_FLAG="--include-sources" || INCLUDE_SOURCES_FLAG=""
SENTRY_CLI="../node_modules/@sentry/cli/bin/sentry-cli"
$SENTRY_CLI debug-files upload "$INCLUDE_SOURCES_FLAG" "$DWARF_DSYM_FOLDER_PATH"
如果您在 React Native 中使用新架构,您可能会缺少 Java 堆栈跟踪。更多详细信息,请参阅 问题。
如果您的构建由于 Sentry CLI 错误而失败,例如没有互联网连接或 sentry.io 不可用,您可以通过添加环境变量 SENTRY_ALLOW_FAILURE
并设置为 true
来允许 sentry-cli
步骤失败。CLI 仍然会运行,但不会导致构建失败:
# iOS
SENTRY_ALLOW_FAILURE=true npx react-native run-ios
# Android
SENTRY_ALLOW_FAILURE=true npx react-native run-android
请注意,如果源映射上传失败,您需要在连接恢复后手动进行 手动上传。
当您在构建命令前移除环境变量时,构建将恢复正常工作。
如果您使用 expo-dev-client,您可能会注意到在开发构建中事务永远不会结束。这是由于开发客户端持续向开发服务器发送日志导致的。要解决此问题,您可以通过在 Sentry.init()
中添加以下内容来停止为发送到日志端点的 HTTP 请求创建跨度:
import * as Sentry from "sentry-expo";
import * as Network from "expo-network";
const devServerPort = 8081;
let devServerIpAddress: string | null = null;
Network.getIpAddressAsync().then((ip) => {
devServerIpAddress = ip;
});
Sentry.init({
tracesSampleRate: 1.0,
integrations: [
new Sentry.Native.ReactNativeTracing({
shouldCreateSpanForRequest: (url) => {
return (
!__DEV__ ||
!url.startsWith(`http://${devServerIpAddress}:${devServerPort}/logs`)
);
},
}),
],
});
如果您使用 React Navigation 的自动路由 instrumentation,路由参数中的敏感数据可能会发送到 Sentry。您可以通过将 SDK 更新到 5.15.2 或更高版本,或使用 beforeSendTransaction
手动删除数据来防止此问题:
Sentry.init({
dsn: "...",
beforeSendTransaction: (event) => {
// delete params as they may contain PII
delete event.contexts?.trace?.data?.route?.params;
delete event.contexts?.trace?.data?.previousRoute?.params;
return event;
},
});
您还可以使用 高级数据清理 在数据存储到服务器端之前过滤掉敏感信息:
[Replace] [Anything] from [contexts.trace.data.route.params]
[Replace] [Anything] from [contexts.trace.data.previousRoute.params]
要从项目中移除 SDK,请运行以下命令:
npx @sentry/wizard -i reactNative -p ios android --uninstall
yarn remove @sentry/react-native
cd ios && pod install
完成上述步骤后,移除 ios/sentry.properties
和 android/sentry.properties
文件。最后,从项目中移除所有使用 @sentry/react-native
的代码。