WIZ-CODE.blog

JavaScriptやAjaxをテーマとしたブログです。

*

独自のエラーメッセージを表示するスクリプト

   

久しぶりの更新になります。あれをやったりこれをやったり、はたまた時間がなくて長期にわたって更新をしなかったりと、あんたいったい何をやりたのかみたいなブログになってきましたが、JavaScriptPHPで色々と楽しいものを作るというコンセプトは維持したいところです。 何度か宣言しているゲーム制作をしたいところですが、色々事情があり停滞しています。その代わり、手の込んでないユーティリティ的なスクリプトはたまに作っています。最近作ったスクリプトはJavaScriptのカスタム例外処理をスムーズに行うやつです。 たとえば値が数値のときだけ処理したい関数があったとして、実際に数値でない値が渡された場合にreturnとかreturn falseにして返り値をundefinedfalseなどにして失敗を意味させることがあります。しかし、それだけで済ますと例外が発生したことに気づきにくいので、あまり得策ではありません。そこで、独自の例外を手軽に出力できないかと、次のスクリプトを書きました。 ThrowException.js (3KB) 軽量、単独で動作。
/*
 * ThrowException.js
 * version 0.1
 * Copyright (c) 2013 Masa (http://wiz-code.digick.jp)
 * 
 */

if (!Array.prototype.forEach) {
	Array.prototype.forEach = function(callback, thisArg) {
		var T, k;

		if (this === null) {
			throw new TypeError('this is null or not defined');
		}

		var O = Object(this);

		var len = O.length >>> 0;

		if ({}.toString.call(callback) !== '[object Function]') {
			throw new TypeError(callback + ' is not a function');
		}

		if (thisArg) {
			T = thisArg;
		}

		k = 0;

		while (k < len) {
			var kValue;

			if (k in O) {
				kValue = O[ k ];
				callback.call(T, kValue, k, O);
			}

			k++;
		}
	};
}

var ThrowException = function (name, data, remedy) {
	if (!(this instanceof ThrowException)) {
		return new ThrowException(name, data, remedy);
	}

	if (typeof data !== 'undefined' ) {
		if (typeof data !== 'function') {
			this.data = data;
			this.remedy = remedy || ThrowException.emptyFunc;
		} else {
			this.data = null;
			this.remedy = data;
		}
	} else {
		this.data = null;
		this.remedy = ThrowException.emptyFunc; 
	}

	var errorObj;
	try {
		ThrowException.errors.forEach(function (value, index, array) {
			if (value.name === name) {
				errorObj = value;
				throw null;
			}
		});
	} catch (e) {}

	if (errorObj) {
		this.name = errorObj.name;
		this.message = errorObj.message;
		this.log();
		this.remedy(errorObj);
	} else {
		console.log('TypeNotExists: そのエラータイプは存在しません。');
	}
};

ThrowException.prototype.log = function () {
	if (this.data !== null) {
		console.log(this.data + ' is ' + this.name + ': ' + this.message);
	} else {
		console.log(this.name + ': ' + this.message);
	}
};

/* ここに独自の例外を追加する */
ThrowException.errors = [
	{name: 'Error', message: 'エラーが発生しました。'},
	{name: 'TypeError', message: '値の型が違います。'},
	{name: 'NotStringException', message: '値が文字列ではありません。'},
	{name: 'NotNumberException', message: '値が数値ではありません。'},
	{name: 'NotBooleanException', message: '値が真偽値ではありません。'},
	{name: 'NotObjectException', message: '値がオブジェクトではありません。'},
	{name: 'NotFunctionException', message: '値が関数ではありません。'},
	{name: 'NotArrayException', message: '値が配列ではありません。'},
	{name: 'ReadError', message: '読み込む値が不正です。'},
	{name: 'WriteError', message: '書き込む値が不正です。'},
	{name: 'ReferenceError', message: '値が参照できません。'}
];

ThrowException.emptyFunc = function () {};
使い方は・・・・・・
 
//文字列なら何らかの処理をする関数
function doSomethingWhenString(str) {
	if (typeof str === 'string') {
		console.log('確かに文字列である!');
		//何らかの処理を行う
	} else {
		//例外を発生させたい場所でThrowExceptionコンストラクタを呼び出す
		//new演算子はあってもなくてもOK。
		//第1引数にエラー名、例外処理をしたい場合は第2引数にコールバック関数を渡す
		ThrowException('NotStringException', function (e) {
			console.log('解決法はこれだ!');
		});
	}
}

//わざと変数に数値を入れで関数を呼び出す
var str = 100;
doSomethingWhenString(str);
//コンソールに「NotStringException: 値が文字列ではありません。」と表示され、
//その下に「解決法はこれだ!」と表示される
 
このカスタムエラーをtry {} catch (e) {}で実装しようとすると、
 
//文字列なら何らかの処理をする関数
function doSomethingWhenString(str) {
	if (typeof str === 'string') {
		console.log('確かに文字列である!');
		//何らかの処理を行う
		//処理が成功したことを示すためtrueを返す
		return true;
	} else {
		//例外を発生させたい場所でカスタムオブジェクトをthrowする
		throw {
			name: 'NotStringException',
			message: '値が文字列ではありません',
			//例外処理はメソッドとして登録しておく
			remedy: function () {
				console.log('解決法はこれだ!');
			}
		};
		//処理が失敗したことを示すためfalseを返す
		return false;
	}
}

//例外を捕捉するためにtry-catch構文を使用する
try {
	var str = 100;
	doSomethingWhenString(str);
	
} catch (e) {
	//例外がthrowされたらここに飛ぶ
	//自力でエラーメッセージを作る
	console.log(e.name + ': ' + e.message);
	//登録しておいた例外処理を実行する
	e.remedy();
}
 
このような形になります。catch文のところでは新たにスコープが作られ面倒な印象がありますね。その点ThrowExceptionは処理内容をコールバックとして渡すので一行で例外のログ出力と処理が記述でき、コードの見通しがよくなると思います。 最初から用意されているカスタムエラーは以上の通りです。それ以外にもコード内のThrowException.errorsという配列に独自のエラーを追加することができます。 ErrorTypeErrorNotStringExceptionNotNumberExceptionNotBooleanExceptionNotObjectExceptionNotFunctionExceptionNotArrayExceptionReadErrorWriteErrorReferenceError

 - JavaScript/Ajax , , ,