자바 스크립트에서 특정 오류 처리 (예외를 생각해보세요)


112

다른 유형의 오류를 어떻게 구현하여 특정 오류를 포착하고 다른 오류가 발생하도록 할 수 있습니다 ..?

이를 달성하는 한 가지 방법은 Error객체 의 프로토 타입을 수정하는 것입니다 .

Error.prototype.sender = "";


function throwSpecificError()
{
    var e = new Error();

    e.sender = "specific";

    throw e;
}

특정 오류 포착 :

try
{
    throwSpecificError();
}

catch (e)
{
    if (e.sender !== "specific") throw e;

    // handle specific error
}


대안이 있습니까?

답변:


159

사용자 지정 예외를 만들려면 Error 개체에서 상속 할 수 있습니다.

function SpecificError () {

}

SpecificError.prototype = new Error();

// ...
try {
  throw new SpecificError;
} catch (e) {
  if (e instanceof SpecificError) {
   // specific error
  } else {
    throw e; // let others bubble up
  }
}

오류에서 상속하지 않는 최소한의 접근 방식은 이름과 메시지 속성이있는 간단한 개체를 던질 수 있습니다.

function throwSpecificError() {
  throw {
    name: 'SpecificError',
    message: 'SpecificError occurred!'
  };
}


// ...
try {
  throwSpecificError();
} catch (e) {
  if (e.name == 'SpecificError') {
   // specific error
  } else {
    throw e; // let others bubble up
  }
}

2
에서 상속하는 데 Error문제가 있습니다. stackoverflow.com/questions/1382107/…
Crescent Fresh

5
이 코드의 문제점 } catch (e) { if (e.name == 'SpecificError') { // specific error } else { throw e; // let others bubble up } }은 IE7에서 작동하지 않아 "Exception thrown and not catch"오류가 발생한다는 것입니다. 다음은 msdn의 매우 어리석은 (항상 그렇듯이) 설명입니다. "Throw 문을 포함했지만 try 블록에 포함되지 않았거나 오류를 잡을 수있는 관련 catch 블록이 없습니다. 예외는 try 블록 내에서 throw됩니다. throw 문을 사용하고 catch 문을 사용하여 try 블록 외부에서 catch했습니다. "
Eugene Kuzmenko 2012 년

1
Microsoft의 C #은 확실히 Javascript : P보다 오류를 더 잘 처리합니다. Mozzilla는 Firefox에 이와 같은 것을 추가했습니다. Ecmascript 표준은 아니지만 ES6도 아니지만 간결하지는 않지만 준수하는 방법도 설명합니다. 기본적으로 위와 동일하지만 instanceOf. 확인 여기
바트

Javascript에서는 간단한 문자열, 숫자 (오류 코드 생각) 또는 정규화 된 객체 등 원하는 것을 던질 수 있습니다. 단!
Abraham Brookes 19 년

1
@LuisNell, 내 코드 예제를 자세히 살펴보면 name생성자 함수 의 속성 사용을 제안하지 않았 음을 알 수 있습니다. name부러지지 않는 속성이 있는 사용자 정의 개체를 던지는 것이
CMS

15

아래 주석에서 언급했듯이 이것은 Mozilla에만 해당되지만 '조건부 catch'블록을 사용할 수 있습니다. 예 :

try {
  ...
  throwSpecificError();
  ...
}
catch (e if e.sender === "specific") {
  specificHandler(e);
}
catch (e if e.sender === "unspecific") {
  unspecificHandler(e);
}
catch (e) {
  // don't know what to do
  throw e;
} 

이것은 적어도 구문 적으로 Java에서 사용되는 형식화 된 예외 처리와 더 유사한 것을 제공합니다.


CMS의 답변과 결합하면 완벽합니다.
Ates Goral

3
조건부 캐치는 이전에 몰랐거나 잊어 버린 것입니다. 교육 / 상기시켜 주셔서 감사합니다! +1
Ates Goral

12
Firefox에서만 지원됩니다 (2.0 이후). 다른 브라우저에서도 구문 분석하지 않습니다. 구문 오류 만 발생합니다.
Crescent Fresh

10
예, 이것은 Mozilla 전용 확장이며 표준화를 위해 제안되지도 않았습니다. 구문 수준 기능이기 때문에이를 스니핑하고 선택적으로 사용할 수있는 방법이 없습니다.
bobince

3
또한 제안 된 솔루션이 표준이 아닙니다. [Mozilla 's JavaScript Reference [( developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ) :This feature is non-standard and is not on a standards track. Do not use it on production sites facing the Web: it will not work for every user. There may also be large incompatibilities between implementations and the behavior may change in the future.
informatik01

10

try-catch-finally.js

사용 시도 - 캐치 finally.js을 , 당신은 호출 할 수 _try는 호출 익명의 콜백과 기능을, 그리고 당신은 체인 수 .catch호출은 특정 오류를 잡으려고하고, .finally호출은 어느 쪽이든을 실행합니다.

_try(function () {
    throw 'My error';
})
.catch(Error, function (e) {
    console.log('Caught Error: ' + e);
})
.catch(String, function (e) {
    console.log('Caught String: ' + e);
})
.catch(function (e) {
    console.log('Caught other: ' + e);
})
.finally(function () {
    console.log('Error was caught explicitly');
});

현대적인 화살표 함수와 템플릿 리터럴을 사용한 예

_try(() => {
  throw 'My error';
}).catch(Error, e => {
  console.log(`Caught Error: ${e}`);
}).catch(String, e => {
  console.log(`Caught String: ${e}`);
}).catch(e => {
  console.log(`Caught other: ${e}`);
}).finally(() => {
  console.log('Error was caught explicitly');
});

2

수출용 모듈

/**
 * Custom InputError
 */
class InputError extends Error {
  /**
   * Create InputError
   * @param {String} message
   */
  constructor(message) {
    super(message);
    this.name = this.constructor.name;
    Error.captureStackTrace(this, this.constructor);
  }
}

/**
 * Custom AuthError
 */
class AuthError extends Error {
  /**
   * Create AuthError
   * @param {String} message
   */
  constructor(message) {
    super(message);
    this.name = this.constructor.name;
    Error.captureStackTrace(this, this.constructor);
  }
}

/**
 * Custom NotFoundError
 */
class NotFoundError extends Error {
  /**
   * Create NotFoundError
   * @param {String} message
   */
  constructor(message) {
    super(message);
    this.name = this.constructor.name;
    Error.captureStackTrace(this, this.constructor);
  }
}

module.exports = {
  InputError: InputError,
  AuthError: AuthError,
  NotFoundError: NotFoundError
};

스크립트로 가져 오기 :

const {InputError, AuthError, NotFoundError} = require(path.join(process.cwd(), 'lib', 'errors'));

사용하다:

function doTheCheck = () =>
  checkInputData().then(() => {
    return Promise.resolve();
  }).catch(err => {
    return Promise.reject(new InputError(err));
  });
};

외부 호출 코드 :

doTheCheck.then(() => {
  res.send('Ok');
}).catch(err => {
  if (err instanceof NotFoundError) {
    res.status(404).send('Not found');
  } else if (err instanceof AuthError) {
    res.status(301).send('Not allowed');
  } else if (err instanceof InputError) {
    res.status(400).send('Input invalid');
  } else {
    console.error(err.toString());
    res.status(500).send('Server error');
  }
});

0

나는 이러한 솔루션을 좋아하지 않아서 직접 만들었습니다. try-catch-finally.js는 시도하기 전에 작은 밑줄 (_) 하나를 잊어 버린 경우 코드가 여전히 잘 실행되지만 아무것도 잡히지 않는다는 점을 제외하면 매우 멋집니다! 왝.

CatchFilter

내 코드에 CatchFilter를 추가했습니다.

"use strict";

/**
 * This catches a specific error. If the error doesn't match the errorType class passed in, it is rethrown for a
 * different catch handler to handle.
 * @param errorType The class that should be caught
 * @param funcToCall The function to call if an error is thrown of this type
 * @return {Function} A function that can be given directly to the `.catch()` part of a promise.
 */
module.exports.catchOnly = function(errorType, funcToCall) {
  return (error) => {
    if(error instanceof errorType) {
      return funcToCall(error);
    } else {
      // Oops, it's not for us.
      throw error;
    }
  };
};

이제 필터링 할 수 있습니다.

이제 C # 또는 Java와 같이 필터링 할 수 있습니다.

new Promise((resolve, reject => {
   <snip><snip>
}).catch(CatchFilter.catchOnly(MyError, err =>
   console.log("This is for my error");
}).catch(err => {
   console.log("This is for all of the other errors.");
});

-2
    <li>
      <span>onWarning:</span>
      <span id="msg_warning"></span>
    </li>

  try {
  // load face detection model
  await changeFaceDetector(MTCNN)
  changeInputSize(128)

  // try to access users webcam and stream the images
  // to the video element

    const stream = await navigator.mediaDevices.getUserMedia({ video: {} })
    const videoEl = $('#inputVideo').get(0)
    videoEl.srcObject = stream
  }
  catch(err) {
    //$("#msg_error").html(`Requested device not found`);
    $("#msg_error").html(err.message);
    console.log(err.message);
  }

안녕하세요, StackOverflow에 오신 것을 환영합니다. 이미 게시 된 다른 5 개의 답변 중에서 귀하의 답변이 더 나은 / 더 효율적 / 기타는 어떻습니까?
mjuarez
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.