Path: csiph.com!weretis.net!feeder7.news.weretis.net!news.albasani.net!.POSTED!not-for-mail From: Thomas 'PointedEars' Lahn Newsgroups: comp.lang.javascript Subject: Exception handling (was: check for obj nested prop) Date: Sat, 09 May 2020 03:46:40 +0200 Organization: PointedEars Software (PES) Lines: 136 Message-ID: <5599059.lOV4Wx5bFT@PointedEars.de> References: <87pnbeycrm.fsf@bsb.me.uk> Reply-To: Thomas 'PointedEars' Lahn Mime-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 8Bit X-Trace: news.albasani.net yhqMWrCNGBTWeZlOmoGRIYbdwlZdwrYQU01BaLfYaLP4HHlSWwx2PqWKfy3z2Yg/SR/KlD/O0PA60/f0JqdA+QScXEjVhB14gy0++mtA6vqOY/njzSYH8xxRN/sfIyCG NNTP-Posting-Date: Sat, 9 May 2020 01:46:40 +0000 (UTC) Injection-Info: news.albasani.net; logging-data="jNLimfAeIl6Qjxv8QdjROkDsWKMzfGKnkOeCAiaE5xi13OTOZidyH2BBB2pIgnO6Cx9c3dF8y0YZueCJa1GTPDbBVAgAkMFOzR2qh2dLNcweFdLEqc2riifj1ZNt0oHt"; mail-complaints-to="abuse@albasani.net" User-Agent: KNode/4.14.10 Face: iVBORw0KGgoAAAANSUhEUgAAADAAAAAwBAMAAAClLOS0AAAAGFBMVEXTxa4RFk5dUWANED8PFEfy7+MGBiW+n3ZNF/QuAAACaElEQVQ4jVXUwVOcMBQG8Dc7Rc4PUntdWV2uxjDpGaGeozOp1woar4jd5t/v9wLstMwsA/ntlxdCAgUc1hjTc9/JCZfGoo3wG3HdmdAWrIJRHe7GM/TmpY5VFefuVcAkkPbLIaN8rmPmjloyZxgyR3GuJ4K0AGtJ2htz8o7yqikm759fldQXaMpbDzjKAG+8v+AugVTOPO5DOjLvGtUYQwh0CPjnVMyGd+8/GfUB5nLKJDD2aLDh5HYyMDJGDwQIo2ZmZcKbowNmAdB/AzyFhrmF2MHRb0QJJfaAnwGB6orZhoykLzJtGwF/xpYxI1dswomiUj3gTuAIqCn/4C7cULwGNBtwMTk3Y4LfKB5YUaOKBKYtpplm7u0vip8tU1NWWyI/7XdcSuIDoMt6rVHMWT0DbjHPGqDqZVSa6zleLcUTcIKLoMv3ueJluALtAo9B302zPPlrtiVScRdCjXvVh3e3JpYa/jjkuC9N+LrBMlz/eAN4eQijX2EdLo6c5tGGHwLyHFtXk89dDGHwCVhG9T0S/j55AhRZgkMCmUQXJ49TnS1wnQDvw0eAh9ICeMmEFbCnPMFzjAvsWoEWEFdYEx+S0MoUZ1gT1wId8+AF3Bl2OoEu906AUHx5VLw/gXYg/x84loOah/2UYNrgiwSwGO7RfUzVBbx/kgpckumGOi6QirtD6gkLTitbnxNol47S2jVc2vsN5kPqaAHT8uUdAJM4v/DanjYOwmUjWznGfwB7sGtAtor5BgofDuzaRj4kSQAqDakTsKORa3Q3xKi3gE1fhl71KRMqrdZ2AWNNg/YOhQyrVBnb+i+nEg4bsDA+egAAAABJRU5ErkJggg== X-Face: %i>XG-yXR'\"2P/C_aO%~;2o~?g0pPKmbOw^=NT`tprDEf++D.m7"}HW6.#=U:?2GGctkL,f89@H46O$ASoW&?s}.k+&. Andrew Poulos writes: >> let obj = {a: 1}; >> if (a.b.c.d) // throws error > > Did you mean if (obj.a.b.c.d) ? Probably yes. >> so I end up doing >> >> if (a && a.b && a.b.c && a.b.c.d) > >> Is there a way to get the check value of an object's nested property >> without first having to test for all the ascendant properties? > > if (try {obj.a.b.c.d} catch {}) > > might do what you want. By contrast, the following is syntactically correct: try { if (obj.a.b.c.d) { // … } } catch {} However, there are several caveats: 1. The omission of the exception parameter requires an implementation of ECMAScript Edition 10 (ECMAScript 2019). This is the most recent Edition of the standard and requires the most recent version of a runtime environment (e.g. a Web browser) to have a chance to be implemented. Compare with 2. Using an empty try-catch block can hide problems in code that are not syntax errors, and is strongly recommended against (as in “SHOULD NOT”). For example, the code above hides a problem of an undeclared identifier “obj” even in strict mode, which would throw a ReferenceError exception. Therefore, if try-catch is used, in almost all cases exception handling should be specific. Unfortunately, ECMAScript did not standardize a feature of Mozilla JavaScript where it was possible to write catch (e if e instanceof ExceptionType) { // … } where ExceptionType would be the exception type, e.g. TypeError, and as of Mozilla JavaScript 68 (Firefox 68) it is removed from the implementation. However, try { } catch (e) { if (e instanceof ExceptionType) { // … } } is functionally equivalent and strictly standards-compliant (specified explicitly in the standard). Finally, exceptions that are not handled should be re-thrown so as to not hide more serious problems: catch (e) { if (e instanceof ExceptionType) { // … } else if (e instanceof …) { // … } else throw e; } 3. With that said, it is actually not easy to tell exception conditions apart. For example, if a property-read access results in the “undefined” value because an object does not have a property with the specified name, then the subsequent lookup of a “nested” property will throw a TypeError exception because “undefined has no properties” (it is a primitive value that cannot be converted to an object). But a TypeError exception is being thrown by several other operations as well (see the standard’s prose), so the recommended *alternative* code try { if (obj.a.b.c.d) { // … } } catch (e) { if (e instanceof TypeError) { // … } else throw e; } is *unable* to tell those conditions apart, and there is none more specific exception type, e.g. a “KeyError“ exception (as it is available for example in Python). Surprising to me, the Airbnb JavaScript Style Guide¹ makes no explicit recommendation or requirement for exception handling. However, they refer to a jsPerf test case for “Try/Catch Cost In a Loop”: Also, you should be aware that while ESLint² supports defining several rules for “throw” and “catch”³, none of them can protect against the problems with exception handling that I discussed above. ______ ¹ ² ³ -- PointedEars FAQ: | | Twitter: @PointedEars2 | Please do not cc me./Bitte keine Kopien per E-Mail.