【问题标题】: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));
}
【解决方案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>
);
}
仍然不确定为什么这对我有用而其他解决方案没有,但认为它值得分享。