Sentry-javascript: ๋ฒ„๊ทธ: ๋ฆด๋ฆฌ์Šค 3.23.2์—์„œ ์˜ค๋ฅ˜๊ฐ€ ์•„๋‹Œ ์˜ˆ์™ธ ์ง๋ ฌ ๋ณ€ํ™˜๊ธฐ๋กœ ์ธํ•ด ์˜ˆ์™ธ ๋ฉ”์‹œ์ง€๊ฐ€ ๋ณ€๊ฒฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์— ๋งŒ๋“  2018๋…„ 03์›” 15์ผ  ยท  3์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: getsentry/sentry-javascript

๋ฆด๋ฆฌ์Šค 3.23.2์—์„œ es6-error (https://www.npmjs.com/package/es6-error)๋กœ ์ƒ์„ฑ๋œ ์˜ค๋ฅ˜๋ฅผ ์ผ์œผํ‚ค๋Š” ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ "Sensible non-Error exception serializer"(#1253) ์˜ค๋ฅ˜ ๋‚ด์šฉ์„ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค.
์ด ์ค„์˜ captureException ํ•จ์ˆ˜์—์„œ ๋ณ€๊ฒฝ๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

options = this._getCaptureExceptionOptionsFromPlainObject(options, ex);

๋” ๊ตฌ์ฒด์ ์œผ๋กœ ๋งํ•˜๋ฉด ๋‹ค์Œ์€ ๋‚ด ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.

import ExtendableError from 'es6-error'

class CustomError extends ExtendableError {
  constructor(code, message) {
    super(message)
    this.name ='CustomError'
    this.code = code
  }
}

export default CustomError

๊ทธ๋Ÿฐ ๋‹ค์Œ ์ฝ”๋“œ์—์„œ:

Raven.captureException(new CustomError('code123', 'not working'));

// this will cause the error message to be "Non-Error exception captured with keys: code"

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

@zivl ๋กœ์ปฌ์—์„œ ํ…Œ์ŠคํŠธํ•˜๊ณ  ํ•ด๋‹น ์ฝ”๋“œ๋กœ ์ž์ฒด custom-error.js ํŒŒ์ผ์„ ๋งŒ๋“ค๊ณ  ๋ชจ๋“ˆ๋กœ ๊ฐ€์ ธ์˜ค๋ฉด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

๋ฌธ์ œ๋Š” ์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์ฝ”๋“œ๋ฅผ "์žˆ๋Š” ๊ทธ๋Œ€๋กœ" ๋‚ด๋ณด๋‚ด์ง€ ์•Š๊ณ  Babel์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฏธ๋ฆฌ ์ปดํŒŒ์ผํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Sooo ๊ทธ๊ฒƒ์€ "์ผ์ข…์˜"์˜ค๋ฅ˜๋กœ ๋๋‚˜์ง€๋งŒ ์‹ค์ œ๋กœ๋Š” ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํŠน์ • ์†์„ฑ์„ ์ƒ์†ํ•˜๊ณ  prototype ๊ฐ€ Error ์ž์ฒด๋กœ ์„ค์ •๋œ ์ผ๋ฐ˜ ๊ฐœ์ฒด์ž…๋‹ˆ๋‹ค.

๋ถˆํ–‰ํžˆ๋„ "์Šˆ๋ขฐ๋”ฉ๊ฑฐ ์˜ค๋ฅ˜"์™€ ๊ฐ™๊ธฐ ๋•Œ๋ฌธ์— ์ˆ˜ํ‘œ ์ˆœ์„œ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ ์™ธ์—๋Š” ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ๋ฐฉ๋ฒ•์ด ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ์˜ค๋ฅ˜์ด๋ฉฐ ๋™์‹œ์— ์˜ค๋ฅ˜๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค.

๋ชจ๋“  3 ๋Œ“๊ธ€

๊ทธ๊ฒƒ์€ JS ๋ชจ๋“ˆ์˜ ๋งค์šฐ ์ด์ƒํ•œ ๋™์ž‘์ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ์„ ์‚ฌ์šฉํ•  ๋•Œ:

import ExtendableError from 'es6-error'

class CustomError extends ExtendableError {
  constructor(code, message) {
    super(message)
    this.name ='CustomError'
    this.code = code
  }
}

function isPlainObject(what) {
  return Object.prototype.toString.call(what) === '[object Object]';
}

function isError(value) {
  switch ({}.toString.call(value)) {
    case '[object Error]':
      return true;
    case '[object Exception]':
      return true;
    case '[object DOMException]':
      return true;
    default:
      return value instanceof Error;
  }
}

function isErrorEvent(value) {
  return Object.prototype.toString.call(value) === '[object ErrorEvent]';
}

var ex = new CustomError('code123', 'not working');

console.log('isPlainObject:', isPlainObject(ex))
console.log('isError:', isError(ex))
console.log('isErrorEvent:', isErrorEvent(ex))

true/true/false ์ž˜๋ชป ๋ณด๊ณ ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ import ๋ฌธ์„ ์ฝ”๋“œ ์ž์ฒด๋กœ ๋Œ€์ฒดํ•  ๋•Œ

class ExtendableError extends Error {
  constructor(message = '') {
    super(message);

    // extending Error is weird and does not propagate `message`
    Object.defineProperty(this, 'message', {
      configurable: true,
      enumerable : false,
      value : message,
      writable : true,
    });

    Object.defineProperty(this, 'name', {
      configurable: true,
      enumerable : false,
      value : this.constructor.name,
      writable : true,
    });

    if (Error.hasOwnProperty('captureStackTrace')) {
      Error.captureStackTrace(this, this.constructor);
      return;
    }

    Object.defineProperty(this, 'stack', {
      configurable: true,
      enumerable : false,
      value : (new Error(message)).stack,
      writable : true,
    });
  }
}

false/true/false ๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋ณด๊ณ ํ•ฉ๋‹ˆ๋‹ค.

์™œ ๊ทธ๋Ÿฐ์ง€ ๋””๋ฒ„๊น…์„ ํ•ด๋ณด๊ณ  ์•Œ ์ˆ˜ ์—†์œผ๋ฉด ๋จผ์ € isError ๋ฅผ ํ†ต๊ณผํ•˜๋„๋ก ์ˆ˜ํ‘œ๋ฅผ ๋ฐ”๊พธ๊ฒ ์Šต๋‹ˆ๋‹ค.

@zivl ๋กœ์ปฌ์—์„œ ํ…Œ์ŠคํŠธํ•˜๊ณ  ํ•ด๋‹น ์ฝ”๋“œ๋กœ ์ž์ฒด custom-error.js ํŒŒ์ผ์„ ๋งŒ๋“ค๊ณ  ๋ชจ๋“ˆ๋กœ ๊ฐ€์ ธ์˜ค๋ฉด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

๋ฌธ์ œ๋Š” ์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์ฝ”๋“œ๋ฅผ "์žˆ๋Š” ๊ทธ๋Œ€๋กœ" ๋‚ด๋ณด๋‚ด์ง€ ์•Š๊ณ  Babel์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฏธ๋ฆฌ ์ปดํŒŒ์ผํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Sooo ๊ทธ๊ฒƒ์€ "์ผ์ข…์˜"์˜ค๋ฅ˜๋กœ ๋๋‚˜์ง€๋งŒ ์‹ค์ œ๋กœ๋Š” ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํŠน์ • ์†์„ฑ์„ ์ƒ์†ํ•˜๊ณ  prototype ๊ฐ€ Error ์ž์ฒด๋กœ ์„ค์ •๋œ ์ผ๋ฐ˜ ๊ฐœ์ฒด์ž…๋‹ˆ๋‹ค.

๋ถˆํ–‰ํžˆ๋„ "์Šˆ๋ขฐ๋”ฉ๊ฑฐ ์˜ค๋ฅ˜"์™€ ๊ฐ™๊ธฐ ๋•Œ๋ฌธ์— ์ˆ˜ํ‘œ ์ˆœ์„œ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ ์™ธ์—๋Š” ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ๋ฐฉ๋ฒ•์ด ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ์˜ค๋ฅ˜์ด๋ฉฐ ๋™์‹œ์— ์˜ค๋ฅ˜๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค.

@zivl ์ด 3.23.3 ์— ์ถœ์‹œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์‹ ๊ณ  ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰