%序言 %
我正在设置 ember-cli-sentry,并希望识别用户,以便在我们报告异常时,我们知道这些异常与哪个用户相关联,以防它们是特定于用户的。(比如说,我们部署到暂存,我们从后端获取了一些糟糕的数据,导致只有将坏数据输入其帐户的用户才会出现某些错误)。
&实际问题 &
我想在用户模型加载后立即执行一些代码。我不知道什么路由会触发用户模型加载。
实际上,从理论上讲,我可以获取用户模型数据的最早位置是在完成对该数据的请求之后立即。我想知道,劫持 XHR 方法会不会很疯狂,当请求用户 ID 时,运行我的代码告诉乌鸦/哨兵这个用户是谁?
如果模型文件只有一个"加载"钩子会更好,但我从未听说过这样的事情。也许这是需要的一个用例?
谷歌/搜索引擎优化的 h1:
Ember:在从任何路由加载模型后执行代码的钩子?如何在从任何路由加载模型后执行代码?
也许在您的主应用程序路由中,您可以执行以下操作:
user: alias('model')
userModelLoaded: observer('user.id', function() {
// execute code to set up Raven
})
我建议要么
在 Ember 数据存储上设置观察- 器 - 有没有办法在 Ember 存储中的任何 Emer 模型更改上设置观察者? - 但这似乎很挑剔,或者;
- 登录路由回调后,设置上下文:
Raven.setUserContext({
email: 'matt@example.com',
id: '123'
});
谢谢@duizendnegen和@Isaac Askew,观察者是一个很好的起点,并引导我找到了最终的解决方案。这个放置在我的应用程序路由中的观察者代码帮助我准确地弄清楚我可以添加什么作为用户上下文:
window.serviceState = {};
// eslint-disable-next-line
let serviceState = window.serviceState;
export default Route.extend(ApplicationRouteMixin, {
// observes services for state changes we care about and stores them in
// a separate variable so when an exception occurs, we can simply include that
// variable and avoid the risk of causing another exception by trying
// to read them in `captureException`
serviceStateTracker: observer(
'service1.prop1',
'service2.propA',
function() {
[
'service1.prop1',
'service2.propA',
].forEach((prop) => {
let newValue = this.get(prop);
if (serviceState[prop] !== newValue) {
if (serviceState[prop] === undefined) {
console.log(prop, newValue);
} else {
console.log(prop, 'changed from:', serviceState[prop], 'to:', newValue);
}
serviceState[prop] = newValue;
}
});
}
),
但是,我确实尝试在异常时间将我关心的道具get
在我的logger
服务中,这效果很好。这更好,因为您不会在每次要记录的属性更改时不必要地执行代码:
// app/services/logr.js
// initially generated with ember-cli-sentry's `ember g logger logr`
import RavenLogger from 'ember-cli-deploy-sentry/services/raven';
import Ember from 'ember';
const { Logger, inject: { service } } = Ember;
export default RavenLogger.extend({
unhandledPromiseErrorMessage: '',
user: service(),
i18n: service(),
addContext() {
if (this == null) {
// eslint-disable-next-line
console.warn('logr cannot addContext because this is null/undefined, continuing without');
return;
}
let tagsContext = {
locale: this.get('i18n.locale'),
id: this.get('user.id'),
firstName: this.get('user.firstName'),
lastName: this.get('user.lastName'),
email: this.get('user.email')
};
// console.log('tagsContext', tagsContext);
// For some reason setUserContext was not working, but setTagsContext was,
// so I am using tags for all the user info. Maybe upgrading raven could fix this?
this.callRaven('setTagsContext', tagsContext);
// why use callRaven: https://github.com/damiencaselli/ember-cli-sentry/issues/58
},
// work around for unmerged PR:
// https://github.com/damiencaselli/ember-cli-sentry/pull/97
captureException(/* error */) {
if (this.get('isRavenUsable')) {
this.addContext();
window.Raven.captureException(...arguments);
} else {
Logger.debug(...arguments);
}
return true;
},
captureMessage(/* message */) {
if (this.get('isRavenUsable')) {
this.addContext();
window.Raven.captureMessage(...arguments);
} else {
Logger.debug(...arguments);
}
return true;
}
});
由于某种原因,观察器无法在我的日志服务中工作。
额外说明:
- 使用 ember-cli-deploy-sentry 插件,不要忘记将该配置放在
config/DEPLOY.js
中,而不是config/environment.js
要触发某个应用程序路由挂钩中的某处错误,请执行以下操作:
setTimeout(() => {
// I was having some issue with `throw new Error()` so I did this instead
// It's actually just a better way to manually 'throw an exception'
// because it will not forcibly crash the application, but instead
// at least attempt to continue running
this.get('logr').captureException(new Error('sentry user context test'));
}, 10000);
- 不要忘记设置
development: false
让 raven 实际将此测试错误发送给哨兵(除非您不是端到端测试)(我通常有这个设置:development: environment === 'development'
在应用程序路由操作中,将此添加到错误操作处理程序:
error(error) {
// Trap unhandled failures during routing:
// Should maybe be handled by the sentry addon, but is not as of now:
// https://github.com/damiencaselli/ember-cli-sentry/issues/105
this.get('logr').captureException(error);