Sentry-javascript: λ°œμƒν•œ λͺ¨λ“  였λ₯˜λ₯Ό μžλ™μœΌλ‘œ κΈ°λ‘ν•˜μ‹œκ² μŠ΅λ‹ˆκΉŒ?

에 λ§Œλ“  2013λ…„ 02μ›” 10일  Β·  31μ½”λ©˜νŠΈ  Β·  좜처: getsentry/sentry-javascript

Raven이 λ˜μ Έμ§„ λͺ¨λ“  였λ₯˜λ₯Ό κΈ°λ‘ν•˜κ²Œ ν•˜λŠ” 방법이 μžˆμŠ΅λ‹ˆκΉŒ? μ–΄λ–€ 이유둜 일뢀 throw ν˜ΈμΆœμ€ κΈ°λ‘ν•˜μ§€λ§Œ λ‹€λ₯Έ ν˜ΈμΆœμ€ κΈ°λ‘ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. 호좜 μŠ€νƒ μ•„λž˜μ— μ€‘μ²©λœ λ™μž‘μ„ κΈ°λ‘ν•˜μ§€ μ•ŠλŠ” κ²½ν–₯이 μžˆμŒμ„ λ°œκ²¬ν–ˆμŠ΅λ‹ˆλ‹€.

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

μ—¬κΈ° μžˆμŠ΅λ‹ˆλ‹€:

var __hasProp = {}.hasOwnProperty,
  __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };

window.Error = (function(_super) {

  __extends(_Class, _super);

  function _Class() {
    var error;
    error = _Class.__super__.constructor.apply(this, arguments);
    Raven.captureException(error);
    return error;
  }

  return _Class;

})(Error);

λͺ¨λ“  31 λŒ“κΈ€

ν•˜ν•˜, Javascript의 였λ₯˜ μ²˜λ¦¬λŠ” 정말 λ”μ°ν•©λ‹ˆλ‹€. 였λ₯˜κ°€ λ°œμƒν•˜λŠ” 방법에 λŒ€ν•œ 예λ₯Ό μ œκ³΅ν•  수 μžˆμŠ΅λ‹ˆκΉŒ?

예λ₯Ό λ“€μ–΄, λ¬Έμžμ—΄μ„ λ˜μ§€λ©΄ 보낸 λ©”μ‹œμ§€λ₯Ό μ œμ™Έν•˜κ³ λŠ” μ–΄λ–€ 정보도 얻을 수 μ—†μŠ΅λ‹ˆλ‹€. μ‹€μ œ Error 개체λ₯Ό μ‚¬μš©ν•˜μ—¬ μŠ€νƒμ„ 얻을 수 μžˆμŠ΅λ‹ˆλ‹€(μ‹œλ„).

λ”°λΌμ„œ 정보가 λ§Žμ„μˆ˜λ‘ μ’‹μŠ΅λ‹ˆλ‹€.

λ¬Όλ‘ .

λ‹€μŒκ³Ό 같은 였λ₯˜κ°€ λ°œμƒν•©λ‹ˆλ‹€.

throw new Error("Error");

μ„ΌνŠΈλ¦¬μ— λ‘œκ·ΈμΈν•  λ•Œλ„ 있고 그렇지 μ•Šμ„ λ•Œλ„ μžˆμŠ΅λ‹ˆλ‹€.

μ–΄λ””μ„ κ°€ λ³Ό 수 μžˆλŠ” νŽ˜μ΄μ§€μΈκ°€μš”? μ•„λ‹ˆλ©΄ μ–΄λ”˜κ°€μ— 넣을 수 μžˆμŠ΅λ‹ˆκΉŒ? μ†”μ§νžˆ, κ·Έκ²ƒλ§ŒμœΌλ‘œλŠ” 정보가 μΆ©λΆ„ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. 였λ₯˜κ°€ κΈ°λ‘λ˜μ§€ μ•ŠλŠ” 이유λ₯Ό μ„€λͺ…ν•  수 μžˆλŠ” μ•½ 10가지 μš”μΈμ΄ 있으며 λŒ€λΆ€λΆ„μ€ 우리의 손을 λ²—μ–΄λ‚˜ μžˆμŠ΅λ‹ˆλ‹€. :) λ”°λΌμ„œ 전체 μ»¨ν…μŠ€νŠΈλ₯Ό λ³Ό 수 μžˆλ‹€λ©΄ λΈŒλΌμš°μ €λ₯Ό λ„μšΈ 수 μžˆλŠ” μ œμ•ˆμ„ λ“œλ¦΄ 수 μžˆμŠ΅λ‹ˆλ‹€.

앱은 μ‹€μ œλ‘œ require.jsλ₯Ό μ‚¬μš©ν•˜μ—¬ JavaScript둜 μ»΄νŒŒμΌλ˜λŠ” CoffeeScript둜 μž‘μ„±λ˜μ—ˆμŠ΅λ‹ˆλ‹€. μ£Όμš” μ§„μž…μ μ€ λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

Raven.config('http://[email protected]');
Raven.context(function() {
  define(['cs!csmain']);
});

context 래퍼 없이도 μ‹œλ„ν–ˆμ§€λ§Œ 아무 것도 λ³€κ²½λ˜μ§€ μ•Šμ€ 것 κ°™μŠ΅λ‹ˆλ‹€. μ—¬μ „νžˆ μ•„λž˜μ— μžˆλŠ” ν˜ΈμΆœμ„ λ¬΄μ‹œν•˜λ©΄μ„œ 호좜 μŠ€νƒμ—μ„œ μƒμœ„μ— 이루어진 throw ν˜ΈμΆœμ„ κΈ°λ‘ν–ˆμŠ΅λ‹ˆλ‹€.

Raven.install() 을(λ₯Ό) μ‹€ν–‰ μ€‘μž…λ‹ˆκΉŒ?

그리고 require.js의 경우 λͺ…μ‹œμ μœΌλ‘œ λͺ¨λ“ˆμ„ λž˜ν•‘ν•˜λ €λ©΄ λ‹€μŒμ„ μˆ˜ν–‰ν•©λ‹ˆλ‹€.

define(['module'], Raven.wrap(function(module) {
  // insert cool stuff here
}));

μŠ€λ‹ˆνŽ«μ—μ„œ μžŠμ–΄λ²„λ Έμ§€λ§Œ config() install() λ₯Ό ν˜ΈμΆœν•©λ‹ˆλ‹€.

λͺ¨λ“ˆμ„ λ‘˜λŸ¬μ‹ΈλŠ” μ‹œλ„λŠ” 해보지 μ•Šμ•˜μ§€λ§Œ 이미 μ–΄λ–€ κ³³μ—μ„œλŠ” μž‘λ™ν•œλ‹€λ©΄ λ‹€λ₯Έ κ³³μ—μ„œλŠ” μ•ˆ λ˜λŠ” μ΄μœ κ°€ λ¬΄μ—‡μΌκΉŒμš”?

그것은 λͺ¨λ‘ μ‹€μ œλ‘œ 호좜 μŠ€νƒμ— 달렀 μžˆμŠ΅λ‹ˆλ‹€. 일이 λΉ„λ™κΈ°ν™”λ˜κΈ° μ‹œμž‘ν•˜λ©΄ κ±°μΉ μ–΄μ§‘λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄ μ˜ˆμƒλŒ€λ‘œ μž‘λ™ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

Raven.context(function() {
  setTimeout(function() {
    throw new Error('crap');
  }, 1);
});

λ‚΄λΆ€ κΈ°λŠ₯은 κΈ°λ³Έ μ»¨ν…μŠ€νŠΈ μ™ΈλΆ€μ˜ 자체 μ»¨ν…μŠ€νŠΈμ—μ„œ μ‹€ν–‰λ©λ‹ˆλ‹€. Node.jsλŠ” "도메인"μ΄λΌλŠ” κ²ƒμœΌλ‘œ 이 문제λ₯Ό ν•΄κ²°ν•˜μ§€λ§Œ μŠ¬ν”„κ²Œλ„ 그런 것듀은 λΈŒλΌμš°μ € μ˜μ—­μ— μ‘΄μž¬ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

λ”°λΌμ„œ 였λ₯˜κ°€ ν¬μ°©λ˜μ§€ μ•Šκ³  맨 λκΉŒμ§€ κ±°ν’ˆμ΄ λ°œμƒν•˜λ©΄ ν•΄λ‹Ή μ‹œμ μ—μ„œ 100% μ“Έλͺ¨κ°€ μ—†κΈ° λ•Œλ¬Έμ— 일반적으둜 κ±°λΆ€λ©λ‹ˆλ‹€.

μ•„, μ•Œκ² μŠ΅λ‹ˆλ‹€. window.onerror λ₯Ό ν™œμš©ν•˜λŠ” 방법이 μžˆμ„κΉŒμš”?

FWIW, κ°€λŠ₯ν•œ 경우 μ˜ˆμ™Έλ₯Ό μΊ‘μ²˜ν•˜λŠ” κ°€μž₯ ν™•μ‹€ν•œ 방법은 Raven.captureException λ₯Ό λͺ…μ‹œμ μœΌλ‘œ μ‚¬μš©ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. 그것이 항상 κ°€λŠ₯ν•œ 것은 μ•„λ‹ˆμ§€λ§Œ 참고용일 λΏμ΄λΌλŠ” 것을 μ΄ν•΄ν•©λ‹ˆλ‹€.

λ”°λΌμ„œ λͺ…μ‹œμ  try...except 블둝이 κ°€μž₯ μ•ˆμ •μ μž…λ‹ˆλ‹€.

try {
  throw new Error('something');
} catch(e) {
  Raven.captureException(e);
}

였λ₯Έμͺ½. λ¬Όλ‘  μžλ™μœΌλ‘œ μ—λŸ¬λ₯Ό μž‘μ•„λ‚΄λ©΄ μ’‹κ² μ§€λ§Œ, μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” κ²Œμž„μ„ μ‰½κ²Œ ν•  수 μžˆλŠ” κ²Œμž„μ΄ μ•„λ‹™λ‹ˆλ‹€...

@퓨터 β€‹β€‹μ•„λ‹ˆμš”. :) 그리고 그것은 μž¬λ―ΈμžˆλŠ” λΆ€λΆ„μž…λ‹ˆλ‹€. window.onerror에 였λ₯˜κ°€ λ°œμƒν•˜λ©΄ 더 이상 μ‹€μ œ Error κ°œμ²΄κ°€ μ•„λ‹™λ‹ˆλ‹€. μ“Έλͺ¨μ—†λŠ” 끈으둜 μΆ•μ†Œλ©λ‹ˆλ‹€. λ˜ν•œ 도메인 κ°„ λ³΄μ•ˆ λ¬Έμ œλ„ λΆ€κ³Όν•©λ‹ˆλ‹€. λ”°λΌμ„œ 기본적으둜 였λ₯˜κ°€ window.onerror 에 λ„λ‹¬ν•˜λ©΄ μš°λ¦¬κ°€ 가진 μœ μΌν•œ μ •λ³΄λŠ” "Script error." 일 수 있기 λ•Œλ¬Έμ— 일반적으둜 νκΈ°λ©λ‹ˆλ‹€.

μ§œμ¦λ‚œλ‹€. 였, μ„€λͺ… κ°μ‚¬ν•©λ‹ˆλ‹€!

μ•„λ‹ˆμš”, μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” 그렇지 μ•ŠμŠ΅λ‹ˆλ‹€. 정말 λ”μ°ν•©λ‹ˆλ‹€. :) λ‚˜λŠ” μš°λ¦¬μ—κ²Œ 더 λ‚˜μ€ 정보λ₯Ό μ œκ³΅ν•˜κΈ° μœ„ν•΄ λΈŒλΌμš°μ €λ₯Ό μ•…μš©ν•˜λŠ” 방법을 적극적으둜 μ—°κ΅¬ν•˜κ³  νƒκ΅¬ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. Function.prototype.call μ›μˆ­μ΄ νŒ¨μΉ˜μ— λŒ€ν•œ 아이디어가 λ‚΄ λ§ˆμŒμ„ λ„˜μ–΄μ„°μŠ΅λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ 그것은 μ•„λ§ˆλ„ 정말 λ‚˜μœ μ†Œμ‹μΌ κ²ƒμž…λ‹ˆλ‹€.

μ™„μ „νžˆ! λ¬Έμ„œλ₯Ό λͺ…ν™•νžˆ ν•˜κΈ° μœ„ν•œ ꢌμž₯ μ‚¬ν•­μ΄λ‚˜ μ œμ•ˆ 사항이 있으면 μ•Œλ €μ£Όμ‹­μ‹œμ˜€. λ‚˜λŠ” 항상 κ·Έ 물건을 μ°Ύκ³  μžˆμŠ΅λ‹ˆλ‹€.

κ·Έλ ‡κ²Œ ν•  κ²ƒμž…λ‹ˆλ‹€. ꡬ성 및 μ‚¬μš© λ¬Έμ„œλŠ” 맀우 κ°„λ‹¨ν•˜κ³  λ”°λΌν•˜κΈ° μ‰½μŠ΅λ‹ˆλ‹€.

이 μž‘μ—…μ„ μˆ˜ν–‰ν•˜κΈ° μœ„ν•΄ Error 을 ν™•μž₯ν•˜λŠ” 방법이 μžˆλŠ”μ§€ κΆκΈˆν•©λ‹ˆλ‹€.

@mattrobenolt , 이것은 CoffeeScriptλ₯Ό μ‚¬μš©ν•˜μ—¬ μš°λ¦¬κ°€ μ·¨ν•˜κ³  μžˆλŠ” μ ‘κ·Ό λ°©μ‹μž…λ‹ˆλ‹€.

window.Error = class extends Error
  constructor: ->
    error = super
    Raven.captureException error
    return error

그런 λ‹€μŒ throw new Error "Test Error" λ₯Ό μ‚¬μš©ν•˜μ‹­μ‹œμ˜€.

μ„€λͺ…을 μœ„ν•΄ μœ„μ˜ μ„€λͺ…을 μ—…λ°μ΄νŠΈν–ˆμŠ΅λ‹ˆλ‹€.

흠. 주말에 μ΄κ²ƒμœΌλ‘œ λ†€μ•„μš”. λ§ˆμ§€λ§‰μœΌλ‘œ μ‹œλ„ν–ˆμ§€λ§Œ window.Error 패치λ₯Ό ν—ˆμš©ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. 더 λ§Žμ€ λΈŒλΌμš°μ €μ—μ„œ λ‹€μ‹œ μ‹œλ„ν•˜κ³  κ°€λŠ₯ν•œμ§€ ν™•μΈν•˜κ² μŠ΅λ‹ˆλ‹€.

κ°μ‚¬ν•©λ‹ˆλ‹€!

λ˜ν•œ 일반 Javascript둜 μ œκ³΅ν•  수 μžˆμŠ΅λ‹ˆκΉŒ? λ‚˜λŠ” 그것이 λ¬΄μ—‡μ„ν•˜κ³  μžˆλŠ”μ§€ κ½€ ν™•μ‹ ν•©λ‹ˆλ‹€. λ‚˜λŠ” 단지 λ‹€μ‹œ ν™•μΈν•˜κ³  μ‹ΆμŠ΅λ‹ˆλ‹€. λ‚˜λŠ” Coffeescriptλ₯Ό 쓰지 μ•ŠλŠ”λ‹€.

μ—¬κΈ° μžˆμŠ΅λ‹ˆλ‹€:

var __hasProp = {}.hasOwnProperty,
  __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };

window.Error = (function(_super) {

  __extends(_Class, _super);

  function _Class() {
    var error;
    error = _Class.__super__.constructor.apply(this, arguments);
    Raven.captureException(error);
    return error;
  }

  return _Class;

})(Error);

μ§€κΈˆ μƒκ°ν•˜λ©΄ 이것은 잘λͺ»λœ μ ‘κ·Ό λ°©μ‹μž…λ‹ˆλ‹€. μƒμ„±μžλ₯Ό μž¬μ •μ˜ν•˜λŠ” κ²ƒλ§ŒμœΌλ‘œλ„ Raven은 λͺ¨λ“  였λ₯˜ κ°œμ²΄κ°€ λ°œμƒν–ˆλŠ”μ§€ 여뢀에 관계없이 λͺ¨λ“  였λ₯˜ 개체λ₯Ό μΊ‘μ²˜ν•˜κ²Œ λ©λ‹ˆλ‹€. :)

참고둜 errorception은 이λ₯Ό μ²˜λ¦¬ν•˜λŠ” 방법을 μ°Ύμ•˜μŠ΅λ‹ˆλ‹€. raven-jsκ°€ λ™μΌν•œ μž‘μ—…μ„ μˆ˜ν–‰ν•  수 μžˆλ‹€λ©΄ λ©‹μ§ˆ κ²ƒμž…λ‹ˆλ‹€.

@dmcquay Errorception이 μΊ‘μ²˜ν•œ 예λ₯Ό μ œκ³΅ν•  수 μžˆμŠ΅λ‹ˆκΉŒ? μ•„λ§ˆ λ¦¬λ²„μŠ€ μ—”μ§€λ‹ˆμ–΄λ§ ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

λ‚˜λŠ” μ‹€μ œλ‘œ λͺ¨λ“  JS 였λ₯˜ ν•Έλ“€λŸ¬κ°€ 50% raven.js라고 κ°€μ •ν•©λ‹ˆλ‹€ ;)

:λ˜₯:

@BYK , μ–΄λ–€ 아이디어가 μžˆμŠ΅λ‹ˆκΉŒ?

λ‚˜λŠ” errorception에 λŒ€ν•œ λ‚΄λΆ€ 지식이 μ—†μŠ΅λ‹ˆλ‹€. μ„œλΉ„μŠ€λ₯Ό μ‚¬μš©ν•˜κ³  있으며 κ΄‘κ³ ν•œ λŒ€λ‘œ μž‘λ™ν•˜λŠ” 것 κ°™μŠ΅λ‹ˆλ‹€. 그게 λ‚΄κ°€ μ•„λŠ” μ „λΆ€ μ•Ό.

λ‚˜λŠ” 그듀이 μ–΄λ–»κ²Œ μž‘λ™ν•˜λŠ”μ§€ μ‘°μ‚¬ν–ˆκ³  λ‹¨μˆœνžˆ window.onerror 에 μžμ‹ μ„ μ—°κ²°ν•˜κ³  μŠ€νƒ 좔적에 μ‹ κ²½ 쓰지 μ•ŠλŠ” κ²ƒμ²˜λŸΌ λ³΄μž…λ‹ˆλ‹€. 적어도 이런 μ’…λ₯˜μ˜ 것듀에 λŒ€ν•΄μ„œλŠ”.

였λ₯˜ 개체λ₯Ό ν•˜μ΄μž¬ν‚Ήν•˜λŠ” 것은 Firefoxμ—μ„œ μž‘λ™ν•˜μ§€λ§Œ @mattrobenolt 의 λͺ¨λ“  μΊ‘μ²˜μ— λŒ€ν•œ μš”μ μ€ throwλ˜μ§€ μ•Šμ€ κ°œμ²΄λΌλ„ μœ νš¨ν•œ λ¬Έμ œμž…λ‹ˆλ‹€.

이에 λŒ€ν•œ λ”λŸ¬μš΄ ν•΄κ²° 방법은 μƒμ„±λœ Error μΈμŠ€ν„΄μŠ€λ₯Ό μ „μ—­ μƒμ„±μžλ₯Ό ν•˜μ΄μž¬ν‚Ήν•˜μ—¬ μ €μž₯ν•˜κ³  onerror λ₯Ό λ“£κ³  message , fileName 및 lineNo λ₯Ό λΉ„κ΅ν•˜λŠ” 것일 수 μžˆμŠ΅λ‹ˆλ‹€.

λͺ¨λ“  였λ₯˜ μ•Œλ¦Ό μ„œλΉ„μŠ€λ₯Ό ν‰κ°€ν•˜λŠ” λ™μ•ˆ 일뢀 Javascript κ΄€λ ¨ μ„œλΉ„μŠ€(예: https://qbaka.com/)κ°€ μŠ€νƒ 좔적을 μΆ”μ ν•˜κ³  νŠΉμ • 였λ₯˜λ₯Ό μœ λ°œν•œ μ‚¬μš©μž μž‘μ—…μ„ ν‘œμ‹œν•œλ‹€λŠ” 것을 μ•Œμ•˜μŠ΅λ‹ˆλ‹€. λ„ˆλ¬΄ λ‚˜μœ errorception은 λ‹€λ₯Έ λͺ¨λ“  λ©΄μ—μ„œ μš°μ›”ν•΄ 보이기 λ•Œλ¬Έμ— κ·Έλ ‡κ²Œ ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

μš°λ¦¬λŠ” Django μ½”λ“œμ— Sentryλ₯Ό μ‚¬μš©ν•  것이며 Sentryκ°€ Javascriptμ—μ„œ μž‘λ™ν•˜λŠ” 방식에 λŒ€ν•œ 정보λ₯Ό μ°ΎλŠ” λ™μ•ˆ 이 문제λ₯Ό λ°œκ²¬ν–ˆμŠ΅λ‹ˆλ‹€. raven-js의 ν˜„μž¬ κ΅¬ν˜„μ—μ„œλŠ” λͺ¨λ“  JS 였λ₯˜λ₯Ό λͺ…μ‹œμ μœΌλ‘œ ν¬μ°©ν•˜κ³  Sentry에 λ³΄κ³ ν•˜λŠ” μ½”λ“œκ°€ ν•„μš”ν•©λ‹ˆκΉŒ?

@adityar7 그렇지 μ•ŠμŠ΅λ‹ˆλ‹€. Raven.jsλŠ” κ°€λŠ₯ν•œ ν•œ μ›μˆ­μ΄ 패치λ₯Ό μ μš©ν•˜κ³  κ°€λ‘œμ±„λŠ” 것이 κ°€μž₯ μ’‹μŠ΅λ‹ˆλ‹€. 더 λ§Žμ€ κ²½μš°μ—λŠ” λͺ…μ‹œμ μœΌλ‘œ λž˜ν•‘ν•΄μ•Ό ν•  μˆ˜λ„ μžˆμ§€λ§Œ μžλ™μœΌλ‘œ 일이 λ°œμƒν•˜λ„λ‘ ν•˜κΈ° μœ„ν•΄ 정말 μ—΄μ‹¬νžˆ λ…Έλ ₯ν•©λ‹ˆλ‹€.

@mattrobenolt 일뢀 ꡬ문을 μˆ˜μ •ν•˜μ—¬ μž‘λ™ν•˜λ„λ‘ ν–ˆμŠ΅λ‹ˆλ‹€. 감사 ν•΄μš”!

이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰