사용자 정의 예외 유형
JavaScript에서 사용자 정의 예외에 대한 사용자 정의 유형을 정의할 수 있습니까?그렇다면 어떻게 해야 할까요?
WebReference에서:
throw {
name: "System Error",
level: "Show Stopper",
message: "Error detected. Please contact the system administrator.",
htmlMessage: "Error detected. Please contact the <a href=\"mailto:sysadmin@acme-widgets.com\">system administrator</a>.",
toString: function(){return this.name + ": " + this.message;}
};
오류에서 프로토타입으로 상속하는 사용자 정의 예외를 만들어야 합니다.예를 들어 다음과 같습니다.
function InvalidArgumentException(message) {
this.message = message;
// Use V8's native method if available, otherwise fallback
if ("captureStackTrace" in Error)
Error.captureStackTrace(this, InvalidArgumentException);
else
this.stack = (new Error()).stack;
}
InvalidArgumentException.prototype = Object.create(Error.prototype);
InvalidArgumentException.prototype.name = "InvalidArgumentException";
InvalidArgumentException.prototype.constructor = InvalidArgumentException;
이는 기본적으로 스택 트레이스가 Firefox 및 기타 브라우저에서 작동한다는 확장 기능을 통해 위에서 설명한 내용을 간략화한 버전입니다.이는 그가 게시한 것과 동일한 테스트를 충족합니다.
사용방법:
throw new InvalidArgumentException();
var err = new InvalidArgumentException("Not yet...");
동작은 다음과 같습니다.
err instanceof InvalidArgumentException // -> true
err instanceof Error // -> true
InvalidArgumentException.prototype.isPrototypeOf(err) // -> true
Error.prototype.isPrototypeOf(err) // -> true
err.constructor.name // -> InvalidArgumentException
err.name // -> InvalidArgumentException
err.message // -> Not yet...
err.toString() // -> InvalidArgumentException: Not yet...
err.stack // -> works fine!
다음과 같이 사용자 고유의 예외 및 해당 처리를 구현할 수 있습니다.
// define exceptions "classes"
function NotNumberException() {}
function NotPositiveNumberException() {}
// try some code
try {
// some function/code that can throw
if (isNaN(value))
throw new NotNumberException();
else
if (value < 0)
throw new NotPositiveNumberException();
}
catch (e) {
if (e instanceof NotNumberException) {
alert("not a number");
}
else
if (e instanceof NotPositiveNumberException) {
alert("not a positive number");
}
}
입력된 예외를 검출하기 위한 다른 구문이 있지만, 일부 브라우저에서는 동작하지 않습니다(예를 들어 IE에서는 동작하지 않습니다).
// define exceptions "classes"
function NotNumberException() {}
function NotPositiveNumberException() {}
// try some code
try {
// some function/code that can throw
if (isNaN(value))
throw new NotNumberException();
else
if (value < 0)
throw new NotPositiveNumberException();
}
catch (e if e instanceof NotNumberException) {
alert("not a number");
}
catch (e if e instanceof NotPositiveNumberException) {
alert("not a positive number");
}
네, 원하는 건 뭐든 던질 수 있어요 정수, 끈, 물체 등요오브젝트를 던지려면 다른 상황에서 오브젝트를 작성한 후 던지듯이 새로운 오브젝트를 작성하기만 하면 됩니다.Mozilla의 Javascript 참조에는 몇 가지 예가 있습니다.
function MyError(message) {
this.message = message;
}
MyError.prototype = new Error;
이를 통해 다음과 같은 사용이 가능합니다.
try {
something();
} catch(e) {
if(e instanceof MyError)
doSomethingElse();
else if(e instanceof Error)
andNowForSomethingCompletelyDifferent();
}
요컨대:
트랜스필러 없이 ES6를 사용하는 경우:
class CustomError extends Error { /* ... */}
현재 베스트 프랙티스는 ES6 구문을 사용한 Javascript 오류 확장을 참조하십시오.
Babel 트랜스필러를 사용하는 경우:
옵션 1: babel-plugin-transform-builtin-extend 사용
옵션 2: 직접 실행(같은 라이브러리에서 영감을 얻음)
function CustomError(...args) {
const instance = Reflect.construct(Error, args);
Reflect.setPrototypeOf(instance, Reflect.getPrototypeOf(this));
return instance;
}
CustomError.prototype = Object.create(Error.prototype, {
constructor: {
value: Error,
enumerable: false,
writable: true,
configurable: true
}
});
Reflect.setPrototypeOf(CustomError, Error);
순수 ES5를 사용하는 경우:
function CustomError(message, fileName, lineNumber) { const instance = new Error(message, fileName, lineNumber); Object.setPrototypeOf(instance, Object.getPrototypeOf(this)); return instance; } CustomError.prototype = Object.create(Error.prototype, { constructor: { value: Error, enumerable: false, writable: true, configurable: true } }); if (Object.setPrototypeOf){ Object.setPrototypeOf(CustomError, Error); } else { CustomError.__proto__ = Error; }
대체 방법: Classtophia 프레임워크 사용
설명:
ES6와 Babel을 사용하여 Error 클래스를 확장하는 것이 문제가 되는 이유는 무엇입니까?
CustomError 인스턴스는 더 이상 인식되지 않기 때문입니다.
class CustomError extends Error {}
console.log(new CustomError('test') instanceof Error);// true
console.log(new CustomError('test') instanceof CustomError);// false
실제로 Babel의 공식 문서에서는 다음과 같은 내장 JavaScript 클래스를 확장할 수 없습니다.Date
,Array
,DOM
★★★★★★★★★★★★★★★★★」Error
.
이 문제는 다음과 같습니다.
- 네이티브 확장에 의해 HTMLEment, 어레이 등이 중단됨
- Array, Number, Object, String 또는 Error와 같은 기본 유형으로 확장되는 클래스의 개체가 이 클래스의 인스턴스가 아닙니다.
다른 SO 답변은요?
모든 됩니다.instanceof
만, 인 에러는 없어집니다.console.log
:
console.log(new CustomError('test'));
// output:
// CustomError {name: "MyError", message: "test", stack: "Error↵ at CustomError (<anonymous>:4:19)↵ at <anonymous>:1:5"}
도 할 수 있습니다.instanceof
인 오류도 합니다.console.log
:
console.log(new CustomError('test'));
// output:
// Error: test
// at CustomError (<anonymous>:2:32)
// at <anonymous>:1:5
ES6
새로운 class 키워드와 extend 키워드를 사용하면 훨씬 쉬워집니다.
class CustomError extends Error {
constructor(message) {
super(message);
//something
}
}
다음은 네이티브와 완전히 동일한 커스텀에러를 작성하는 방법입니다.Error
의 동작.이 기술은 현재 Chrome과 node.js에서만 작동합니다.만약 당신이 그것의 기능을 이해하지 못한다면 나도 그것을 사용하는 것을 추천하지 않을 것이다.
Error.createCustromConstructor = (function() {
function define(obj, prop, value) {
Object.defineProperty(obj, prop, {
value: value,
configurable: true,
enumerable: false,
writable: true
});
}
return function(name, init, proto) {
var CustomError;
proto = proto || {};
function build(message) {
var self = this instanceof CustomError
? this
: Object.create(CustomError.prototype);
Error.apply(self, arguments);
Error.captureStackTrace(self, CustomError);
if (message != undefined) {
define(self, 'message', String(message));
}
define(self, 'arguments', undefined);
define(self, 'type', undefined);
if (typeof init == 'function') {
init.apply(self, arguments);
}
return self;
}
eval('CustomError = function ' + name + '() {' +
'return build.apply(this, arguments); }');
CustomError.prototype = Object.create(Error.prototype);
define(CustomError.prototype, 'constructor', CustomError);
for (var key in proto) {
define(CustomError.prototype, key, proto[key]);
}
Object.defineProperty(CustomError.prototype, 'name', { value: name });
return CustomError;
}
})();
재기동하면
/**
* name The name of the constructor name
* init User-defined initialization function
* proto It's enumerable members will be added to
* prototype of created constructor
**/
Error.createCustromConstructor = function(name, init, proto)
그 후 다음과 같이 사용할 수 있습니다.
var NotImplementedError = Error.createCustromConstructor('NotImplementedError');
그리고 사용NotImplementedError
당신이 하고 싶은 대로Error
:
throw new NotImplementedError();
var err = new NotImplementedError();
var err = NotImplementedError('Not yet...');
동작은 다음과 같습니다.
err instanceof NotImplementedError // -> true
err instanceof Error // -> true
NotImplementedError.prototype.isPrototypeOf(err) // -> true
Error.prototype.isPrototypeOf(err) // -> true
err.constructor.name // -> NotImplementedError
err.name // -> NotImplementedError
err.message // -> Not yet...
err.toString() // -> NotImplementedError: Not yet...
err.stack // -> works fine!
주의:error.stack
절대적인 정확성을 가지며 포함시키지 않는NotImplementedError
컨스트럭터 콜(v8 덕분에)Error.captureStackTrace()
).
참고. 못생긴 게 있어.eval()
이것을 사용하는 유일한 이유는 정답을 얻기 위해서입니다.err.constructor.name
필요 없는 경우에는 모든 것을 조금 심플하게 할 수 있습니다.
나는 종종 원형 유전에 대한 접근 방식을 사용한다.덮어쓰기toString()
Firebug와 같은 툴이 실제 정보를 기록할 수 있는 이점을 제공합니다.[object Object]
콘솔에 액세스 할 수 있습니다.
사용하다instanceof
예외 유형을 판별합니다.
main.discloss.main.discloss.
// just an exemplary namespace
var ns = ns || {};
// include JavaScript of the following
// source files here (e.g. by concatenation)
var someId = 42;
throw new ns.DuplicateIdException('Another item with ID ' +
someId + ' has been created');
// Firebug console:
// uncaught exception: [Duplicate ID] Another item with ID 42 has been created
예외.js
ns.Exception = function() {
}
/**
* Form a string of relevant information.
*
* When providing this method, tools like Firebug show the returned
* string instead of [object Object] for uncaught exceptions.
*
* @return {String} information about the exception
*/
ns.Exception.prototype.toString = function() {
var name = this.name || 'unknown';
var message = this.message || 'no description';
return '[' + name + '] ' + message;
};
DuplicateIdException 입니다.js
ns.DuplicateIdException = function(message) {
this.name = 'Duplicate ID';
this.message = message;
};
ns.DuplicateIdException.prototype = new ns.Exception();
throw 문을 사용합니다.
JavaScript는 (Java와 마찬가지로) 예외 유형이 무엇이든 상관하지 않습니다.JavaScript는 단지 알아채기만 하면 예외가 발생하며, 이를 포착하면 예외가 "발송"하는 내용을 "확인"할 수 있습니다.
던져야 하는 예외 유형이 다른 경우 예외 문자열/개체를 포함하는 변수(예: 메시지)를 사용하는 것이 좋습니다.필요한 경우 "throw myException"을 사용하고 catch에서 포착된 예외를 myException과 비교합니다.
MDN 의 이 예를 참조해 주세요.
에러를 복수 정의할 필요가 있는 경우(여기에서 코드를 테스트합니다).
function createErrorType(name, initFunction) {
function E(message) {
this.message = message;
if (Error.captureStackTrace)
Error.captureStackTrace(this, this.constructor);
else
this.stack = (new Error()).stack;
initFunction && initFunction.apply(this, arguments);
}
E.prototype = Object.create(Error.prototype);
E.prototype.name = name;
E.prototype.constructor = E;
return E;
}
var InvalidStateError = createErrorType(
'InvalidStateError',
function (invalidState, acceptedStates) {
this.message = 'The state ' + invalidState + ' is invalid. Expected ' + acceptedStates + '.';
});
var error = new InvalidStateError('foo', 'bar or baz');
function assert(condition) { if (!condition) throw new Error(); }
assert(error.message);
assert(error instanceof InvalidStateError);
assert(error instanceof Error);
assert(error.name == 'InvalidStateError');
assert(error.stack);
error.message;
코드는 대부분 다음에서 복사됩니다.JavaScript에서 오류를 확장하는 좋은 방법은 무엇입니까?
ES2015 클래스와 함께 사용할 수 있는 애셀린의 답변에 대한 대안
class InvalidArgumentException extends Error {
constructor(message) {
super();
Error.captureStackTrace(this, this.constructor);
this.name = "InvalidArgumentException";
this.message = message;
}
}
//create error object
var error = new Object();
error.reason="some reason!";
//business function
function exception(){
try{
throw error;
}catch(err){
err.reason;
}
}
이제 오류 개체에 이유 또는 원하는 속성을 추가하고 가져옵니다.에러를 합리화함으로써.
언급URL : https://stackoverflow.com/questions/464359/custom-exception-type
'source' 카테고리의 다른 글
VueJS 자동화 - 테스트 카페와나이트워치 - 장점 / 단점 (0) | 2022.11.08 |
---|---|
Python에서 유형을 확인하는 표준 방법은 무엇입니까? (0) | 2022.11.08 |
자바에는 eval() 함수가 있나요? (0) | 2022.11.08 |
Java reflection을 사용하여 메서드 파라미터명을 얻을 수 있습니까? (0) | 2022.11.08 |
JSON 개체 크기 가져오기 (0) | 2022.11.08 |