【问题标题】:Where to set Sentry's setUser in Next.js app?在 Next.js 应用程序中在哪里设置 Sentry\'s setUser?
【发布时间】:2022-08-13 07:41:28
【问题描述】:

我一直在尝试将用户数据全局设置到 Sentry 的范围内,因此每次出现错误或事件时,都会将用户信息传递给它。

我的应用程序是在 Next.js 中构建的,所以我很自然地添加了配置,因为它在 Sentry 的 Next.js 文档中。

我不知道在哪里添加 Sentry.setUser({id: user.Id}) 方法以便全局设置用户。

到目前为止,我已将它添加到 Sentry\ 的 _error.js 文件中,在 getInitialProps 方法中:

import NextErrorComponent from \'next/error\';

import * as Sentry from \'@sentry/nextjs\';
import { getUser } from \'../lib/session\';

const MyError = ({ statusCode, hasGetInitialPropsRun, err }) => {
    if (!hasGetInitialPropsRun && err) {
        Sentry.captureException(err);
    }

    return <NextErrorComponent statusCode={statusCode} />;
};

MyError.getInitialProps = async (context) => {
    const errorInitialProps = await NextErrorComponent.getInitialProps(context);

    const { req, res, err, asPath } = context;

    errorInitialProps.hasGetInitialPropsRun = true;

    const user = await getUser(req, res);

    // Set user information
    if (user) {
        console.log(\'Setting user\');
        Sentry.setUser({ id: user.Id });
    }
    else {
        console.log(\'Removing user\');
        Sentry.configureScope(scope => scope.setUser(null));
    }

    if (res?.statusCode === 404) {
        return errorInitialProps;
    }


    if (err) {
        Sentry.captureException(err);

        await Sentry.flush(2000);

        return errorInitialProps;
    }

    Sentry.captureException(
        new Error(`_error.js getInitialProps missing data at path: ${asPath}`),
    );
    await Sentry.flush(2000);

    return errorInitialProps;
};

export default MyError;

但是当尝试记录错误时,用户信息不会显示在 Sentry 中,只有默认用户 ip:

成功登录后我也尝试设置用户,但仍然没有..

帮助表示赞赏!

    标签: javascript reactjs next.js sentry


    【解决方案1】:

    我建议使用 callback handler 设置您的 Sentry 用户上下文。

    import { handleAuth, handleLogin, handleCallback } from "@auth0/nextjs-auth0";
    import * as Sentry from "@sentry/nextjs";
    import { NextApiHandler } from "next";
    
    const afterCallback = (_req, _res, session, _state) => {
      Sentry.setUser({
        id: session.user.sub,
        email: session.user.email,
        username: session.user.nickname,
        name: session.user.name,
        avatar: session.user.picture,
      });
      return session;
    };
    
    const handler: NextApiHandler = handleAuth({
      async login(req, res) {
        await handleLogin(req, res, {
          returnTo: "/dashboard",
        });
      },
      async callback(req, res) {
        try {
          await handleCallback(req, res, { afterCallback });
        } catch (error) {
          res.status(error.status || 500).end(error.message);
        }
      },
    });
    
    export default Sentry.withSentry(handler);
    
    

    【讨论】:

      【解决方案2】:

      您可以在成功登录后立即在 Sentry 中设置用户

      const handleLogin = {
        try {
          const res = await axios.post("/login", {"john@example.com", "password"})
          if (res && res?.data) {
            // Do other stuff
            Sentry.setUser({ email: "john@example.com" });
          }
        }
      }
      
      

      此外,您可以在注销时清除用户

      const handleLogout = {
        // Do othe stuff
        Sentry.configureScope(scope => scope.setUser(null));
      }
      

      【讨论】:

      • 已经试过了,什么都没有..仍然只得到IP
      • axios拦截器怎么样?
      【解决方案3】:

      不确定这是否是正确的方法,但上述解决方案对我不起作用。所以我尝试在_app.tsx 中调用 setUser。

      import { useEffect } from "react";
      import { setUser } from "@sentry/nextjs";
      import { UserProvider, useUser } from "@auth0/nextjs-auth0";
      import type { AppProps } from "next/app";
      
      function SentryUserManager() {
        const { user } = useUser();
      
        useEffect(() => {
          if (user) {
            setUser({
              email: user.email ?? undefined,
              username: user.name ?? undefined,
            });
          } else {
            setUser(null);
          }
        }, [user]);
        return null;
      }
      
      export default function MyApp({ Component, pageProps }: AppProps) {
        return (
          <UserProvider>
            <Component {...pageProps} />
            <SentryUserManager />
          </UserProvider>
        );
      }
      

      仍然不确定为什么这对我有用而其他解决方案没有,但认为它值得分享。

      【讨论】:

        猜你喜欢
        • 2013-06-19
        • 1970-01-01
        • 2016-04-21
        • 2011-09-23
        • 2012-03-13
        • 2018-03-28
        • 2013-06-27
        • 2021-02-26
        • 2012-01-25
        相关资源
        最近更新 更多