【问题标题】:Sentry - React - capture errors iframe and only iframeSentry - React - 捕获错误 iframe 并且仅捕获 iframe
【发布时间】:2020-03-06 09:25:29
【问题描述】:

上下文
我们正在开发一个基于 React 的应用程序,它被用作其他网站上的“小部件”。我们的整个 React 应用程序使用 react-frame-component 包装在 iframe 中。

出于开发目的,我们使用Sentry 记录任何错误 (@sentry/browser sdk)。

问题
我们注意到,一旦我们的应用程序被集成到任何网站上,错误就不会再被记录到 Sentry,我们不完全确定如何解决这个问题。

因此,我们正在寻求一种解决方案,以将 iframe 内发生且仅在该 iframe 内发生的错误记录到 Sentry。

是否有可能以某种方式告诉 Sentry 使用哪个窗口/目标/范围?

使用React Error Boundaries 可能是一个值得考虑的选项。但是,它不会捕获所有错误。

iframe - 代码

...
render(
    <Iframe initialContent={initialIframeContent}>
        <App />
    </Iframe>,
    document.getElementById(containerId)
);
...

Sentry 集成 - 代码

...
Sentry.init({
    environment: env,
    dsn: SENTRY_DSN
});
...

【问题讨论】:

  • 你有什么运气吗?我有一个非常相似的情况
  • @NicholasHaley 抱歉回复晚了。我刚刚添加了我们的解决方案作为答案

标签: reactjs sentry


【解决方案1】:

我们找不到直接的解决方案,因此我们最终使用 React 错误边界来捕获任何崩溃并将其记录到哨兵。

请记住,错误边界不会捕获所有崩溃(请参阅下面的引用)。所以我们想出了一个钩子,它可以让错误边界也捕获这些崩溃(除了服务器端渲染和错误边界本身内部的崩溃)。

inspiration hook

注意

错误边界不会捕获以下错误:

  • 事件处理程序(了解更多)
  • 异步代码(例如 setTimeout 或 requestAnimationFrame 回调)
  • 服务器端渲染
  • 在错误边界本身(而不是其子项)中引发的错误

~React

ErrorBoundary.js

const initialState = {
    hasError: false,
    showError: false
};

export default class ErrorBoundary extends Component {
    static propTypes = {
        children: PropTypes.node.isRequired
    };

    static getDerivedStateFromError () {
        return { hasError: true };
    }

    state = initialState;

    componentDidCatch (error) {
        logToSentry(error);
    };
    ...

sentry docs

useError.js

const useError = () => {
    const [_, setError] = useState();

    return useCallback(
        e => {
            setError(() => {
                throw e;
            });
        },
        [setError],
    );
};

export default useError;

使用示例

const throwError = useError();

const someAsyncFn = useCallback(async () => {
    try {
        const response = await asyncApiRequest();
    } catch (e) {
        throwError(e)
    }
}, []);

const someEventHandler = useCallback(async () => {
    try {
        doSomethingThatMightCrash();
    } catch (e) {
        throwError(e)
    }
}, []);

这有点乏味,可能有一些方法可以进一步简化它,但它确实发挥了作用。

【讨论】:

    猜你喜欢
    • 2018-03-17
    • 2013-02-12
    • 1970-01-01
    • 1970-01-01
    • 2019-05-27
    • 1970-01-01
    • 1970-01-01
    • 2012-07-13
    • 1970-01-01
    相关资源
    最近更新 更多