ugrás a tartalomhoz

Az elnyelt hibaüzenetek és a Prototype

Pusztai Tibor · 2007. Már. 29. (Cs), 16.35
Aktívan használsz Prototype-ot, és olyan érzésed van, hogy nem kapod meg a JS hibaüzeneteket? Arról van szó, hogy a Prototype az Ajax.Request-nek átadott onComplete függvényt (és az egyéb callback-eket) egy try...catch blokk belsejéből hívja meg (ezzel szerintem eléggé megnehezítve a hibakeresést), s így a böngészőben semmi nyoma nem marad a hibának, és az oldal nem működik. Most vajon hol fogj hozzá a kereséshez?

Ha találkoztál már ilyennel, akkor próbáld ki a megoldásom, melynek lényege, hogy a Prototype-os AJAX kérésekre bevezet egy eseménykezelőt, mely hiba esetén nem elnyeli, hanem újból kiváltja az eredeti hibát:

(
	function() {
		var origConstructor = Ajax.Request.prototype.initialize;
		Ajax.Request.prototype.initialize = function(url, options) {
			origConstructor.bind(this)(url, Object.extend(options, {
				onException: function(_, exp) {throw exp}
			}));
		}
	}
)();
A kis kiegészítő használata nagyon egyszerű, szúrd be a Prototype behúzása után bárhova, és utána ott láthatod majd mosolyogni a kivételeket a Firebug konzolján. :)
 
1

Nem igazán értem

amonrpg · 2007. Ápr. 4. (Sze), 14.29
Szóval nem igazán értem én ezt. A Prototype Ajax.Request-je (pontosabban az Options) tartalmaz egy onException callback lehetőséget. Ideális pl. logolni a hibákat. Nem hiszem, hogy megnehezíti a hibakeresést, ha csak nem arra gondolsz, hogy a végtermék nem köpködi a felesleges hibákat a végfelhasználó felé, de neked lehetőséged van a logolásra. Ettől függetlenül a fenti kódrészlet még akár hasznos is lehet, ha kiegészíted kikapcsolási lehetőséggel. Pontosabban csak akkor fusson le, ha mondjuk van egy debug:1 paramétered.
2

Persze, debug-hoz

Pusztai Tibor · 2007. Ápr. 4. (Sze), 17.26
Természetesen én is úgy gondoltam, hogy ez a fejlesztést segíti, nem pedig egy kész termék minőségét javítja. Általában nem ugyanaz az optimális fejlesztéshez és "kiadáshoz". Lásd egy c++ fordítónál: debug vs. release verzió, előfordító direktívák, precompiling stb... Szerintem az egy külön (és érdekes) téma, hogy ezek szétválasztására milyen módszerek vannak javascript esetén.

Javascript-ben, ha egy egy kódrészhez nem definiálsz kivételkezelőt, akkor a böngésző kapja meg őket, ha definiálsz és nem dobott feljebb, akkor Te. Ez a prototype Ajax.Request-nél nem így van, mert ott az elnyelés az alapértelmezett, és akkor kell foglalkozni vele, ha meg akarod kapni vagy elő akarod idézni. Nem mondom, hogy ez rossz, szemlélet kérdése. Viszont akkor szerintem a többi függvénynek ill. funkciónak is így kellene működnie, ez így nem következetes.

Így jobban tetszik?
(
    function() {
        var origConstructor = Ajax.Request.prototype.initialize;
        Ajax.Request.prototype.initialize = function(url, options) {
            origConstructor.bind(this)(url, options.onException ?
                options :
                Object.extend(options, {
                    onException: function(_, exp) {throw exp}
                })
            );
        }
    }
)();
Mindenesetre fejlesztéshez az első a jobb (hacsaknem egy épp ezzel kapcsolatos részt tesztelsz), viszont ez utóbbit szerintem nyugodt szívvel benne lehet hagyni egy felhasználóknak szánt változatban is. Ha pedig amúgy nem használsz saját kivételkezelőt, akkor édesmindegy.
3

nos igen

amonrpg · 2007. Ápr. 4. (Sze), 21.57
Szerintem jobb. :D
Mondjuk nem állt szándékomban belekötni. Csak a weben - tapasztalataim szerint - azért annyira nem különül el a fejlesztési- és a publikálási szakasz, mint egy fordított program esetében. Így a felhasznált eszközök is általában inkább a debug- és nem debug-módokat támogatják.
Egy nagyobb projektnél meg végképp szükséges (megint csak szerintem), hogy egy darab jelzővel lehessen ki- és bekapcsolni pl a debug módot, vagy a logolást, s ne N+1 helyen kelljen beleirogatni.

Persze, ha amúgy compile-szerűen nyomja ki az ember a release-t (pl. mert jsmin-nel végigtolja a JS fájlokat), akkor ez nem annyira érdekes.