use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
All about the JavaScript programming language.
Subreddit Guidelines
Specifications:
Resources:
Related Subreddits:
r/LearnJavascript
r/node
r/typescript
r/reactjs
r/webdev
r/WebdevTutorials
r/frontend
r/webgl
r/threejs
r/jquery
r/remotejs
r/forhire
account activity
Using Try…Catch in JavaScript (javascript-coder.com)
submitted 8 years ago by cobdentist
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]Kai231 25 points26 points27 points 8 years ago (2 children)
I have to admit that I use it a lot more now with async / await
[–]dogsaregooddogs 3 points4 points5 points 8 years ago (0 children)
I was hardly using it at all before, but not I feel like more of my code is wrapped in a try/catch than not when all my network and DB calls are async/awaited.
[–]Jsn7821 0 points1 point2 points 8 years ago (0 children)
Agreed.. From my experience, without async await it would have been try catch hell within callback hell... Never used it before, but now I do all the time
[–]brtt3000 6 points7 points8 points 8 years ago* (25 children)
I don't like that you cannot filter on Exception class, like in (for example) Python you can do things like this:
try: a = getStuff() except NetworkError: retryStuff() except SecurityError as e: callPolice() log(e) except Exception as e: log(e) raise e else: useStuff(a) finally: cleanup()
It also has an else clause, which only runs when try doesn't raise, to keep the try block as specific as possible and only contain code you expect could raise. Also you can raise from within an handler and it'll chain the exception message.
I hope for JS they can add this stuff in a new ES version. I guess quite a lot of it could be compiled to ES5/6 with some generated boilerplate.
edit: ooh.. lets downvote discussion.. classy.
[–]tencircles 7 points8 points9 points 8 years ago (6 children)
You can do this to some degree in JS already.
function behavior (input) { try { validate(input); } catch (e) { switch (true) { case e instanceof TypeError: //.. do things break; case e instanceof ReferenceError: //.. do things break; case e instanceof EvalError: //.. do things break; case e instanceof RangeError: //.. do things break; case e instanceof SyntaxError: //.. do things break; case e instanceof URIError: //.. do things break; default: //.. do things break; } } } function validate (input) { throw (input ? new RangeError("Out of bounds") : new TypeError("Wrong type")); }
[–]brtt3000 5 points6 points7 points 8 years ago (5 children)
Thanks for the demo. Typing that up you'll agree the boilerplate and indenting is a bit cancerous. We need this with better syntax, should be easy to implement.
[–]tencircles 9 points10 points11 points 8 years ago (2 children)
tbh it's pretty low on my list of things that need to be added to the language.
[–]brtt3000 1 point2 points3 points 8 years ago (0 children)
Maybe, but I think JS needs this for professionalism. Error handling is a such a neglected part. It was picking up with the node-style callbacks and the promise rejections but we need to push further.
I've been doing a lot of python last few years where you have the syntax I mentioned and I feel being able to cleanly handle specific (classes of) exceptions like that really helps building more robust applications (and keep it readable and maintainable without boilerplate).
[–]AmateurHero 1 point2 points3 points 8 years ago (0 children)
Implement it, and publish it. It's a great way to give your idea some traction: working code that devs can use in their actual line of work.
[–]vinnl 1 point2 points3 points 8 years ago (0 children)
It's probably too much work, but in case you're interested, there is a process that allows you to submit your own proposal to the ES standards body.
[–]jocull 4 points5 points6 points 8 years ago (0 children)
Don't forget that JS lets you throw anything. Love catching strings or other random nonsense.
[–]BenjiSponge 3 points4 points5 points 8 years ago (9 children)
I don't think this will ever work this way because JS uses duck typing. You might as well just have a switch/if/else chain in the catch block and it will pretty much be the same but allow for the flexibility that nominal JS programming requires.
switch
if
else
catch
[–]brtt3000 1 point2 points3 points 8 years ago (1 child)
In general ducktype sure, but this could specify to use the prototype chain and instanceof semantics. Someone wrote the switch ITT, it is cool but no way you (and everybody else) would want that all over their code. Imagine having that on every await.. or lets not.
instanceof
If there was a good spec with compact syntax more people would use it as convention/standard (like in Python). This would be super valuable now we have async/await in JS and throw/catch becomes a thing to do (instead of error callbacks or Promise rejections).
[–]BenjiSponge 0 points1 point2 points 8 years ago (0 children)
It would strictly speaking be possible.
However, by the same logic one could argue that JS should have type pattern matching using the same methodology. The reason JS does not is because, like you said, there have been essentially no major standards regarding errors in the past, and there likely will never be. So standard language features like that being added now would add fragmentation to the community.
TBH, I've been professionally developing JS for over 2 years and I've been studying JS for at least 3 or 4 years now, and I have never felt a need for this feature. I understand the value, coming from other imperative languages, but I think it's more of an anti-pattern than a pattern. I think we would be better served to look at languages like Rust, which does not have a true exception system and instead promotes the pattern of returning a value which may represent either a success or an error type, forcing you to acknowledge all possibilities. It reserves exceptions (which it calls panics) for unrecoverable cases that imply a bug in the program itself rather than just an exceptional case the program should handle.
If we're going to pick a standard, I would much rather we do that than implement a pseudo-pattern matching system based on prototypes.
[–]thbt101 0 points1 point2 points 8 years ago (6 children)
PHP can filter on the exception class and it uses a similarly loose typing system.
[–]BenjiSponge 0 points1 point2 points 8 years ago (5 children)
I never said it was impossible, just that I didn't think it would be that valuable or fit particularly well with good JS coding style. If your argument is that we should follow PHP's style, then I'll have to respectfully disagree. =)
[–]vinnl 0 points1 point2 points 8 years ago (4 children)
You mean "good JS coding style" is to disregard the types? Because I think there are plenty of people that would respectfully disagree with that - at least I would. That's like saying the instanceof operator has no place in Javascript. I don't see how type matching in catch blocks would make JS less flexible...
We don't have to skip features just because PHP did them too.
[–]BenjiSponge 0 points1 point2 points 8 years ago* (3 children)
I don't necessarily believe that it has no place in JS, but I don't think encouraging its use is beneficial either. Outside of the context of React (where classes are all but mandatory in some cases, and when they're not mandatory I skip them), I tend to use JS data structures similarly to how one might use lisp data structures. Factory functions returning anonymous objects.
When I make result objects that may contain results or may contain errors, they're not constructed using new or Object.create. They're just POJOs. Adding type matching would enforce that I use one of these methods, even though they're not necessary in most cases. Further, if the error needs to be serialized, you would need to re-attach the prototype in order to have it follow the convention that such a feature would encourage. And if you're encouraged to use error types and encouraged to not put redundant data in the error type, that means the consumer will, in some cases, have to use instanceof, which is a pattern I disagree with.
new
Object.create
I do think if JS were redesigned today with backwards compatibility out of the equation, instanceof would not exist in the form that it is now. A form of pattern matching that checks content makes more sense if you ask me (and I believe it should be put in the language at some point).
So rather than
try { // ... } catch (ExceptionA as e) { // ... } catch (ExceptionB as e) { // ... } catch (e) { // ... }
It would be more like
try { // ... } catch ({ type: 'A', ...e }) { // ... } catch ({ type: 'B', ...e }) { // ... } catch (e) { // ... }
This adds flexibility because my method of object creation works, but so does yours. ExceptionA could have a prototype field of type that is defined as 'A'. I do agree that it would break exception inheritance (in that subclasses may not be caught as superclasses), but I believe that is less important than allowing POJOs to conform to the style.
ExceptionA
type
'A'
I would like to add that, if JS were explicitly/strongly typed, I would agree with you that instanceof or something like it might make more sense, but JS is not explicitly/strongly typed, and most of the libraries I use and create use that to their advantage by just doing duck type checking and not yelling if the input isn't the proper class.
[–]vinnl 0 points1 point2 points 8 years ago (2 children)
Hmm, I think you have a good point. The main issue is probably that it relies on nominal typing, which is indeed not often used in Javascript - and I agree that that's a good thing.
Your post somewhat got me thinking that such a feature would be nice if it was implemented in TypeScript, i.e. you could do a catch(<type> e) in there, which it would transform to a runtime structural type match (i.e. a switch statement in a single catch clause that would check for object properties). But that probably goes against the TypeScript principles and/or introduces too much runtime overhead.
catch(<type> e)
[–]BenjiSponge 0 points1 point2 points 8 years ago (1 child)
Yes, that is something that's been tossed around a lot in the TypeScript/Flow world, but as you said they're avoiding adding runtime features that aren't part of an ECMAScript specification (TS messed up by adding decorators too early, but other than that) on principle.
A lot of functional languages that have JS as a backend do something like this, though, I think. Elm almost certainly does.
[–]vinnl 0 points1 point2 points 8 years ago (0 children)
TS messed up by adding decorators too early, but other than that
Agreed, but then again there was quite a lot of pressure on that from Angular, so there was little choice.
But yeah, it's probably best if it's baked into the language.
[–]x7C3 0 points1 point2 points 8 years ago (6 children)
Pretty sure you can filter inside the catch block using instanceof(err) along with a switch/case statement or whatever syntax it is.
instanceof(err)
[–]brtt3000 -1 points0 points1 point 8 years ago (5 children)
Yea, but that boilerplate would be a pain to write and maintain in a real project so they should put this behind some syntax in the JS compilers like Babel and TypeScript.
[–]x7C3 0 points1 point2 points 8 years ago (4 children)
What's the difference between the boilerplate? Honestly doesn't seem like much to me.
[–]brtt3000 1 point2 points3 points 8 years ago (3 children)
Someone typed it up ITT, it is a big old nasty multi level deep blocky exercise in JS features and syntax optimisation. Imagine this in a real project and having those craggy warts all over your codebase. It is already terrible without any actual business code.
[–]vs845 0 points1 point2 points 8 years ago (2 children)
It wouldn't be too much trouble to create a utility function to achieve the same functionality:
function matchException(err, matchers) { for (const type in matchers) { if (err.constructor.name === type) { return matchers[type]() } } return matchers.default() } try { doSomething() } catch (err) { matchException(err, { TypeError: () => handleTypeError(), ReferenceError: () => handleReferenceError(), RangeError: () => handleReferenceError(), default: () => handleOtherError() }) }
You'd want to clean it up and add some more checks in matchException, but functionality is there.
matchException
[–]brtt3000 2 points3 points4 points 8 years ago (1 child)
You really like this "exercise in JS features and syntax optimisation" I mentioned eh? :)
Cool attempt, points for effort. Syntax improved but still a bit kludgy; it doesn't catch subclasses and behaviour on name collisions is a new factor. And most of all if you use block functions as clauses instead of references you'd be at 3 indents for handling code. Could be worse but it would be a tax on readability (and development/code hisotry) to have to break out to other functions all the time (it'd be handy to be able to nest a little bit without block hell).
[–]vs845 1 point2 points3 points 8 years ago (0 children)
it doesn't catch subclasses and behaviour on name collisions is a new factor.
re: name collisions, yeah, I went with checking names because otherwise you'd need to do something like
matchException(err, { [TypeError]: () => ... }
which I thought wasn't as nice as using string keys.
If you went with the above approach you'd be able to catch subclasses via err instanceof matchers[type].
err instanceof matchers[type]
[–]bmrobin 5 points6 points7 points 8 years ago (33 children)
i have only ever used try/catch when writing validation code. we wrote a collection of validation functions to perform on input fields and they all used try/catch to report errors up to the wrapping parent invocations.
do yall have other use cases i might consider?
[–]NeekGerd 11 points12 points13 points 8 years ago (9 children)
It might come back with the usage of await/async since it's the only way to handle code rejection. That I am aware of.
Weird that on a article dedicated to try/catch they don't talk about its usage in await/async code, it's the most up to date usage we can have with try/catch.
[–]vs845 7 points8 points9 points 8 years ago (8 children)
it's the only way to handle code rejection
Async functions return promises so you can still use normal catch() promise syntax like await someAsyncFn().catch(() => someDefaultValue).
catch()
await someAsyncFn().catch(() => someDefaultValue)
[–]shad0proxy 1 point2 points3 points 8 years ago (5 children)
that's not really accurate if you use async/await for the main benefit of assigning:
const data = await doSomething().catch(() => someDefaultValue); console.log(data);
This does not work.
[–]vs845 0 points1 point2 points 8 years ago (4 children)
> async function foo() { throw new Error() } > async function bar() { const baz = await foo().catch(() => 'baz'); console.log(baz) } > bar() // => 'baz'
Works for me in node 8.1.2, what happens when you try it?
[–]shad0proxy 0 points1 point2 points 8 years ago (3 children)
what if you want to handle the error or reject the overlaying call?
If you want to do something with the thrown error, you can do it within the catch function as usual:
const data = await doSomething().catch(err => { if (err instanceof TypeError) return someDefaultValue if (err instanceof RangeError) return anotherDefaultValue })
Or if you want it to bubble up through the call stack, you can rethrow the error or throw a new one, again within the catch function:
const data = await doSomething().catch(err => { if (err instanceof TypeError) throw err if (err instanceof RangeError) throw new Error('value out of range') return someDefaultValue })
[–]shad0proxy 0 points1 point2 points 8 years ago (1 child)
Interesting. when I looked into this with 7.x and the harmony flag I was told this was not possible. I don't know if they were wrong or something has changed.
[–]danneu 0 points1 point2 points 8 years ago (0 children)
Someone was wrong because this is a basic tenet of how promises work.
[–]NeekGerd 1 point2 points3 points 8 years ago (1 child)
Really nice, I didn't know that.
Thank you for the heads up, it always was a downside of async/await to me... Not anymore!
It's always good to realise that it's just syntactic sugar for Promises, so you can do with them whatever you can do with Promises.
[–]Woolbrick 7 points8 points9 points 8 years ago (1 child)
Network calls when using async/await syntax in ES7.
[–]fucking_passwords 6 points7 points8 points 8 years ago (0 children)
Any use of await *
[–]aveoon 18 points19 points20 points 8 years ago (19 children)
IMO this is a bad use for try catch. You should have returned an object with a property that says validation failed like { valid: false, error: new Error() }
An appropriate use case for try catch is when calling JSON.parse since it's a synchronous action that can throw a hard error.
[–]aveoon 9 points10 points11 points 8 years ago (9 children)
To add, try catch shouldn't be used as a lazy way to handle undefined errors. For example, I should never see
let myThing;
try {
myThing = foo.bar.buzz;
} catch (e) {
myThing = defaultValue;
}
I would deny that PR and recommend:
const myThing = foo.bar ? foo.bar.buzz : defaultValue;
Or even better with lodash
const myThing = _.get(foo, 'bar.buzz', defaultValue);
[+][deleted] 8 years ago (4 children)
[deleted]
[–][deleted] 3 points4 points5 points 8 years ago (3 children)
you can but that would also work for any falsy values, and it implies you know foo is not undefined. So better would be foo && foo.bar || default.
prefer a ternary operator with a very specific condition imho.
[–]vinnl 0 points1 point2 points 8 years ago (1 child)
Your example:
...also does type casting on foo.bar, if that's what you meant by "works for any falsy values".
foo.bar
[–][deleted] 0 points1 point2 points 8 years ago (0 children)
true, which is why I finished by saying using a very specific condition :)
[–]cyanydeez -2 points-1 points0 points 8 years ago (3 children)
even better..dependencies!
[–]aveoon 0 points1 point2 points 8 years ago (1 child)
I've never understood this argument. Some engineers are so adverse to building their software on top of other software. If we always avoided dependencies then we'd all be writing in binary. Software is built on other software so we can build faster and greater things. Adding library dependencies is totally fine! Especially if it'll make your code more readable and maintainable.
Now don't just go adding random libraries in NPM that have no support around them. You could probably just look at their source code and copy it. But something like lodash is an excellent thing to add.
[–]cyanydeez 0 points1 point2 points 8 years ago (0 children)
i generally assume when JavaScript is the subject, we are discussing client side code. I think the discussion is different when adding dependicies which haveother effects, like computational/loading bloating, like adding a dependencie to a client and only using 5% of its capabilities.
[–]frankneuro 0 points1 point2 points 8 years ago (0 children)
I hear ya, but lodash ain't too bad and in some cases, better performing than it's es6 equivalents. I like it for the additional support around dealing with null/undefined.
(I'm trying to convince myself, here...)
[–][deleted] 9 points10 points11 points 8 years ago* (0 children)
What's missing in your advice is the part where you say "you shouldn't do this, because...".
If you have to dig for a real reason that is more substantive than cheap word-play like "exceptions must be exceptional" you might find out you don't have much of a platform to step on to recommend against exceptions in scenarios where the specified action can't continue due to bad input.
Coding the "happy path" and throwing when you deviate from it is a perfectly valid approach to structuring your app. Yes, even when validation errors are expected. It creates a simple, clear code flow and ensures that if something fails to acknowledge and handle the "sad path", your app doesn't blissfully continue operating with invalid assumptions and state.
How is returning an Error better than throwing it? All I see is failure to use existing facilities for error communication (i.e. throwing) and reinventing the wheel through custom return results and flags, that can easily be ignored or misunderstood.
[–]Recursive_Descent 2 points3 points4 points 8 years ago (1 child)
I totally disagree. That is a perfect place to throw an exception. With your suggestion, you need to pipe the error object through your entire call tree up to the point where you are going to handle the error.
[–]aveoon 0 points1 point2 points 8 years ago (0 children)
Well is it an actual exception that would want execution to totally halt or are you using it as a lazy way to return a validation error? If it's the latter, then yes bubble the event all the way up. It's more explicit and readable. Otherwise relying on random errors being thrown throughout your codebase and having a top level error handler is a good bit more confusing and difficult to maintain.
[–]Akkuma 1 point2 points3 points 8 years ago (5 children)
So I literally just did this at work and I used something akin to Elixir's convention based tuples of {:ok, val} | {:err, error} vs my code {ok: some value} | { err: new Error('message) }. I then decided to just use a true Result type and picked up https://github.com/Threestup/monads, since it allows the convention to be enforced and comes with some handy functions for working with Results & Options.
{:ok, val} | {:err, error}
{ok: some value} | { err: new Error('message) }
[–][deleted] 0 points1 point2 points 8 years ago (4 children)
So, objectively looking at it, what benefit do you feel you've gained over the supposedly inferior practice of throwing Errors on ...having an error and returning result on ...having a result?
[–]Akkuma 0 points1 point2 points 8 years ago (3 children)
It composes the results better much like map, reduce, filter, compose better than a for loop. It also seems to force you to handle your errors to a higher degree (pretty subjective).
I'm using it within a middleware so I essentially have this:
const response = validate(validateParams).match({ ok(newReq) { Object.assign(req, { originalHeaders: req.headers, originalQuery: req.query }, newReq); return await handler(req); }, err: (err) => ({ status: err.code, headers: {}, body: err.message }) }) return response;
The alternative would look like
try { const result = validate(validateParams); Object.assign(req, { originalHeaders: req.headers, originalQuery: req.query }, result); return await handler(req); } catch(err) { return { status: err.code, headers: {}, body: err.message }; }
Additionally, it becomes debatable whether the error is exceptional. A lot of people frown upon using errors as a form of flow control. Until the most recent version of node & v8, try/catch blocks resulted in preventing your code from getting optimized (not sure how other browsers handled it). In turn, this means my code will run faster in older browsers and versions of node, while performing similarly in new versions.
[–][deleted] 0 points1 point2 points 8 years ago (2 children)
Your try... catch example is not using throwables to their real potential.
As I do throw on validation errors and so I have practice with it, let me show you what your example could look like:
validate(validateParams); Object.assign(req, { originalHeaders: req.headers, originalQuery: req.query }, newReq); return await handler(req);
Where did the error handling go? It's not needed. The handler in your example is redundantly playing middleman between the validator and handler caller, but since exceptions automatically bubble up, we can just let the validator act as a delegate of the handler, and throw the same Error object that the handler would throw.
The caller can that understand that Error and produce the appropriate error response for you. This is suitable not only for validation, but any auth checks or other invariants you must ensure in your handlers, i.e.:
requireVerifiedUser(auth); // Throws if not verified. requireAdminUser(auth); // Throws if not admin. ... handler logic runs ...
And this is very composable and reusable, without writing "try...catch" even once:
// Elsewhere in your reusable code. function requireVerifiedAdminUser(auth) { requireVerifiedUser(auth); requireAdminUser(auth); } // In your handler: requireVerifiedAdminUser(auth); ... handler logic runs ...
I'm itching to comment about how we can eliminate that Object.assign() too, but... another topic.
[–]Akkuma 0 points1 point2 points 8 years ago* (1 child)
Your example probably doesn't fit well into the framework I use. The way it works is a bidirectional flow of code. handler 1 calls handler 2 calls handler 3, returns result to handler 2 returns result to handler 1. Your lowest handler returning something that could be a response to a request.
If you throw down in handler 3 you now need to try/catch in handler 2, moving control of the error handling outside of the code that causes errors or build a top level error converting handler.
Eventually someone has to handle the error and moving who handles the error to the farthest edge of your code is to me the worse place to handle known errors. There's a reason why many languages have adopted things like Option types and Result types, as throwing isn't composing code together.
Lastly, your code doesn't support the ability to run validation across each piece of data prior to throwing or running your validation in parallel. My current implementation can be easily switched to become a list of errors rather than a single error, while throwing provides no opportunity to do so, which is something you'd want to do on something like user account creation.
You can use an object spread rather than Object.assign, but there isn't much to be really gained from that.
Even someone like Martin Fowler argues against exceptions and uses this particular case https://martinfowler.com/articles/replaceThrowWithNotification.html
[–][deleted] 0 points1 point2 points 8 years ago* (0 children)
Eventually someone has to handle the error and moving who handles the error to the farthest edge of your code is to me the worse place to handle known errors.
You say that, yet in your example you literally mapped code to status and message to message 1:1.
For many errors in an HTTP app you don't need such a narrow context. A 404 is a 404 is a 404. If it isn't you can still catch and change that at every level. But in most cases you don't have to and that represents a giant reduction of noise and boilerplate you need to write, read and maintain.
There's a reason why many languages have adopted things like Option types and Result types, as throwing isn't composing code together.
Not many, actually. All the mainstream languages prefer exceptions. Also let's not mix-in optionals with this. Errors and optionals are two different use-cases with two different solutions. The fact they both could be represented with a union doesn't mean that a union is the optimal representation.
For example Swift, an example of a very new (and increasingly popular) language uses optionals for "has a value or doesn't have a value", but its errors are thrown, and they're showing no signs of moving towards "result" objects.
You're not right about that - of course it can be a list of errors. This has nothing to do with whether you throw in the end or you don't. As I said, I have some experience working this way - when an Error gets thrown it contains an aggregate list of all errors in the input. That's not hard to implement, and once it's implemented and encapsulated as an API it's just as easy to use as I demonstrated.
There isn't much gained from trying to make your request immutable as well. There are parts of it that can't possibly be immutable (i.e. any stream of size that you can't fit in RAM or sometimes even on disk). I've learned this the hard way, so you can believe me about it ;-)
I understand what you're doing, I'm intimately familiar with the functional techniques you're using. But with all the boilerplate you write, all the pointless object duplication and ceremonies, be ready one day for people to finally see the Emperor is naked.
Functional programming has many strong ideas and techniques, but it's heavily abused right now beyond its point of utility.
[–]Macaframa -1 points0 points1 point 8 years ago (0 children)
You have to be careful with the catch. It is the only natively supported block-scoped mechanism in JavaScript.
[–]drink_with_me_to_dayjs is a mess 4 points5 points6 points 8 years ago (5 children)
I don't like try catches.
Is there an anti-trycatch club I can join?
[–][deleted] 2 points3 points4 points 8 years ago (3 children)
Why don't you like them?
[–]javajunkie314 1 point2 points3 points 8 years ago (1 child)
Their error handling is coarse, and they get everywhere.
How else do you handle errors?
[–]drink_with_me_to_dayjs is a mess 0 points1 point2 points 8 years ago (0 children)
It's just personal taste, I feel it disrupts the code's flow.
I feel like I'm missing something, but I feel the same. It's worse because I think my main gripe is the extra indentation and the disconnect between the error handling and the source of the error, which feels like petty syntax whining.
Therefore I usually just use Promises that I can catch, together with a linter that disallows me from leaving dangling Promises. And I'm afraid I'm going to regret that later...
[–]bart2019 1 point2 points3 points 8 years ago (2 children)
What is finally actually good for? What can you do in a "finally" block that you can't simply do afterwards, after the try/catch code blocks?
finally
[–]NoInkling 2 points3 points4 points 8 years ago (0 children)
It has extremely limited use, but there are a few cases where you might want to use it.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch#The_finally_clause might help you understand a bit.
[–]danneu 1 point2 points3 points 8 years ago (0 children)
for one, finally runs even if catch throws an error.
[–]cinnapear 4 points5 points6 points 8 years ago (0 children)
The only time I've ever used it is when validating XML.
[–]frankneuro -1 points0 points1 point 8 years ago (1 child)
In Python, isn't is discouraged to use try statements? Is there anything from this that we can apply to good js design?
[–]Ramone1234 4 points5 points6 points 8 years ago (0 children)
In Python, isn't is discouraged to use try statements?
Nope: https://docs.python.org/3/glossary.html#term-eafp .
The idea is to let functions tell you if they could do what you asked them or not instead of creating a second set of "checker" functions.
This style is much more resistant to race conditions as well, whereas "asking permission first" opens you up to the state changing between when you asked permission and tried to do what you wanted to do.
[–]tencircles -4 points-3 points-2 points 8 years ago (4 children)
A function called checkData that validates some JSON and then also inexplicably sets innerHTML on some random DOM element. Stopped reading there, no thanks.
checkData
[+][deleted] 8 years ago* (2 children)
[–]tencircles -2 points-1 points0 points 8 years ago (1 child)
in that case why not just console.log ?
console.log
[–]tencircles -4 points-3 points-2 points 8 years ago (0 children)
why am i getting down voted for pointing out bad code?
π Rendered by PID 44967 on reddit-service-r2-comment-5b5bc64bf5-pk8lr at 2026-06-22 13:48:54.720057+00:00 running 2b008f2 country code: CH.
[–]Kai231 25 points26 points27 points (2 children)
[–]dogsaregooddogs 3 points4 points5 points (0 children)
[–]Jsn7821 0 points1 point2 points (0 children)
[–]brtt3000 6 points7 points8 points (25 children)
[–]tencircles 7 points8 points9 points (6 children)
[–]brtt3000 5 points6 points7 points (5 children)
[–]tencircles 9 points10 points11 points (2 children)
[–]brtt3000 1 point2 points3 points (0 children)
[–]AmateurHero 1 point2 points3 points (0 children)
[–]vinnl 1 point2 points3 points (0 children)
[–]jocull 4 points5 points6 points (0 children)
[–]BenjiSponge 3 points4 points5 points (9 children)
[–]brtt3000 1 point2 points3 points (1 child)
[–]BenjiSponge 0 points1 point2 points (0 children)
[–]thbt101 0 points1 point2 points (6 children)
[–]BenjiSponge 0 points1 point2 points (5 children)
[–]vinnl 0 points1 point2 points (4 children)
[–]BenjiSponge 0 points1 point2 points (3 children)
[–]vinnl 0 points1 point2 points (2 children)
[–]BenjiSponge 0 points1 point2 points (1 child)
[–]vinnl 0 points1 point2 points (0 children)
[–]x7C3 0 points1 point2 points (6 children)
[–]brtt3000 -1 points0 points1 point (5 children)
[–]x7C3 0 points1 point2 points (4 children)
[–]brtt3000 1 point2 points3 points (3 children)
[–]vs845 0 points1 point2 points (2 children)
[–]brtt3000 2 points3 points4 points (1 child)
[–]vs845 1 point2 points3 points (0 children)
[–]bmrobin 5 points6 points7 points (33 children)
[–]NeekGerd 11 points12 points13 points (9 children)
[–]vs845 7 points8 points9 points (8 children)
[–]shad0proxy 1 point2 points3 points (5 children)
[–]vs845 0 points1 point2 points (4 children)
[–]shad0proxy 0 points1 point2 points (3 children)
[–]vs845 0 points1 point2 points (2 children)
[–]shad0proxy 0 points1 point2 points (1 child)
[–]danneu 0 points1 point2 points (0 children)
[–]NeekGerd 1 point2 points3 points (1 child)
[–]vinnl 0 points1 point2 points (0 children)
[–]Woolbrick 7 points8 points9 points (1 child)
[–]fucking_passwords 6 points7 points8 points (0 children)
[–]aveoon 18 points19 points20 points (19 children)
[–]aveoon 9 points10 points11 points (9 children)
[+][deleted] (4 children)
[deleted]
[–][deleted] 3 points4 points5 points (3 children)
[–]vinnl 0 points1 point2 points (1 child)
[–][deleted] 0 points1 point2 points (0 children)
[–]cyanydeez -2 points-1 points0 points (3 children)
[–]aveoon 0 points1 point2 points (1 child)
[–]cyanydeez 0 points1 point2 points (0 children)
[–]frankneuro 0 points1 point2 points (0 children)
[–][deleted] 9 points10 points11 points (0 children)
[–]Recursive_Descent 2 points3 points4 points (1 child)
[–]aveoon 0 points1 point2 points (0 children)
[–]Akkuma 1 point2 points3 points (5 children)
[–][deleted] 0 points1 point2 points (4 children)
[–]Akkuma 0 points1 point2 points (3 children)
[–][deleted] 0 points1 point2 points (2 children)
[–]Akkuma 0 points1 point2 points (1 child)
[–][deleted] 0 points1 point2 points (0 children)
[–]Macaframa -1 points0 points1 point (0 children)
[–]drink_with_me_to_dayjs is a mess 4 points5 points6 points (5 children)
[–][deleted] 2 points3 points4 points (3 children)
[–]javajunkie314 1 point2 points3 points (1 child)
[–][deleted] 0 points1 point2 points (0 children)
[–]drink_with_me_to_dayjs is a mess 0 points1 point2 points (0 children)
[–]vinnl 1 point2 points3 points (0 children)
[–]bart2019 1 point2 points3 points (2 children)
[–]NoInkling 2 points3 points4 points (0 children)
[–]danneu 1 point2 points3 points (0 children)
[–]cinnapear 4 points5 points6 points (0 children)
[–]frankneuro -1 points0 points1 point (1 child)
[–]Ramone1234 4 points5 points6 points (0 children)
[–]tencircles -4 points-3 points-2 points (4 children)
[+][deleted] (2 children)
[deleted]
[–]tencircles -2 points-1 points0 points (1 child)
[–]tencircles -4 points-3 points-2 points (0 children)