Ember sentry/raven:加载用户模型时设置用户上下文?

Ember sentry/raven: set user context when user model loads?

% 序言 %

我正在设置 ember-cli-sentry 并希望识别用户,以便当我们收到异常报告时,我们知道这些异常与哪个用户相关联,以防它们是特定于用户的. (比如,我们部署到暂存区,我们从后端获得了一些错误数据,导致某些错误,只有将这些错误数据输入到他们帐户中的用户才会出现)。

&真题&

我想在加载用户模型后立即执行一些代码。我不知道什么路由将触发用户模型加载。

理论上,实际上,我最早可以获得用户模型数据的地方是在对该数据的请求完成之后。我想知道,劫持XHR方法会不会很疯狂,当请求用户id时,运行我的代码告诉raven/sentry这个用户是谁?

如果模型文件有一个 "loaded" 钩子就更好了,但我从来没有听说过这样的东西。也许这是一个需要这样做的用例?

google/seo 的 h1:

Ember:从任何路径加载模型后挂钩执行代码?从任何路由加载模型后如何执行代码?

也许在你的 main application route 中你可以这样做:

user: alias('model')

userModelLoaded: observer('user.id', function() {
  // execute code to set up Raven
})

我会建议

  • 在您的 Ember 数据存储上设置观察者 - - 但这似乎很挑剔,或者;
  • 登录路由回调后,设置上下文:

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;
  }
});

出于某种原因,观察者无法在我的 logr 服务中工作..

补充说明:

  • 使用 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);