- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Accidentally catching NonLocalReturnException
Sat, 2010-01-23, 18:15
Hello everyone,
I have a code:
def something(): Unit = {
val collection = ...
collection foreach x => {
try {
// ...
return
} catch {
case t:Throwable => doSomething(); throw new MyOwnException(t)
}
}
}
This breaks when return is executed. I know this return is implemented
by throwing a NonLocalReturnException and I should not catch it. But how
to handle such cases when I really, really have to catch all exceptions?
I work this around by rethrowing NonLocalReturnException:
} catch {
case t:NonLocalReturnException => throw t
case t:Throwable => doSomething(); throw new MyOwnException(t)
}
Is it a good workaround, or is there something better recommended?
Anyway, are there chances that when Java 7 is released, the non local
return will be done by something faster than exceptions?
Regards,
Piotr
Sat, 2010-01-23, 19:17
#2
Re: Accidentally catching NonLocalReturnException
Catching Throwable is generally something to avoid.
Also, since Scala doesn't employ checked exceptions, I usually don't feel the need to wrap exceptions either.
Cheers,
Viktor Klang
| "A complex system that works is invariably
| found to have evolved from a simple system
| that worked." - John Gall
Blog: klangism.blogspot.com
Twttr: twitter.com/viktorklang
Code: github.com/viktorklang
2010/1/23 Rex Kerr <ichoran@gmail.com>
Also, since Scala doesn't employ checked exceptions, I usually don't feel the need to wrap exceptions either.
Cheers,
Viktor Klang
| "A complex system that works is invariably
| found to have evolved from a simple system
| that worked." - John Gall
Blog: klangism.blogspot.com
Twttr: twitter.com/viktorklang
Code: github.com/viktorklang
2010/1/23 Rex Kerr <ichoran@gmail.com>
That looks to me like a good workaround.
In general, returns (especially non-local ones like you've shown) are not encouraged, as it makes understanding code flow more difficult.
If you can, consider using a functional alternative (though it admittedly cannot cover all the same cases):
collection.iterator.takeWhile( /*condition */).foreach(x => /* code */)
(use elements instead of iterator in 2.7.x). Another less-functional idea:
var collected = false;
val collection = /*...*/;
collection.find( x => {
try {
stuff
if (/*things are good*/) collected = true;
}
catch { stuff }
collected
} )
--Rex
2010/1/23 Piotr Kołaczkowski <pkolaczk@elka.pw.edu.pl>
Hello everyone,
I have a code:
def something(): Unit = {
val collection = ...
collection foreach x => {
try {
// ...
return
} catch {
case t:Throwable => doSomething(); throw new MyOwnException(t)
}
}
}
This breaks when return is executed. I know this return is implemented by throwing a NonLocalReturnException and I should not catch it. But how to handle such cases when I really, really have to catch all exceptions? I work this around by rethrowing NonLocalReturnException:
} catch {
case t:NonLocalReturnException => throw t
case t:Throwable => doSomething(); throw new MyOwnException(t)
}
Is it a good workaround, or is there something better recommended?
Anyway, are there chances that when Java 7 is released, the non local return will be done by something faster than exceptions?
Regards,
Piotr
Sat, 2010-01-23, 19:57
#3
Re: Accidentally catching NonLocalReturnException
Viktor Klang pisze:
> Catching Throwable is generally something to avoid.
>
> Also, since Scala doesn't employ checked exceptions, I usually don't
> feel the need to wrap exceptions either.
Yes, I know, but sometimes you do not know which exceptions to expect
from a module written by another programmer, so you end up catching
Throwable just for safety that your module won't crash and logging it
somewhere (this particular piece of code had to do with plugins
developed by third parties). The wrapping was not for purpose of making
checked exception unchecked as often is done in Java, but to tell the
caller some more information about what caused the exception (which
plugin, etc.).
And catching a NonLocalReturnException was a surprise :)
Regards,
Piotr Kołaczkowski
>
> Cheers,
>
> Viktor Klang
> | "A complex system that works is invariably
> | found to have evolved from a simple system
> | that worked." - John Gall
>
> Blog: klangism.blogspot.com
> Twttr: twitter.com/viktorklang
> Code: github.com/viktorklang
>
>
> 2010/1/23 Rex Kerr >
>
> That looks to me like a good workaround.
>
> In general, returns (especially non-local ones like you've shown)
> are not encouraged, as it makes understanding code flow more difficult.
>
> If you can, consider using a functional alternative (though it
> admittedly cannot cover all the same cases):
>
> collection.iterator.takeWhile( /*condition */).foreach(x => /* code */)
>
> (use elements instead of iterator in 2.7.x). Another
> less-functional idea:
>
> var collected = false;
> val collection = /*...*/;
> collection.find( x => {
> try {
> stuff
> if (/*things are good*/) collected = true;
> }
> catch { stuff }
> collected
> } )
>
> --Rex
>
> 2010/1/23 Piotr Kołaczkowski
> >
>
> Hello everyone,
>
> I have a code:
>
>
> def something(): Unit = {
>
> val collection = ...
> collection foreach x => {
>
> try {
>
> // ...
> return
>
> } catch {
> case t:Throwable => doSomething(); throw new MyOwnException(t)
> }
> }
> }
>
>
> This breaks when return is executed. I know this return is
> implemented by throwing a NonLocalReturnException and I should
> not catch it. But how to handle such cases when I really, really
> have to catch all exceptions? I work this around by rethrowing
> NonLocalReturnException:
>
> } catch {
> case t:NonLocalReturnException => throw t
> case t:Throwable => doSomething(); throw new MyOwnException(t)
> }
>
>
> Is it a good workaround, or is there something better recommended?
> Anyway, are there chances that when Java 7 is released, the non
> local return will be done by something faster than exceptions?
>
> Regards,
> Piotr
>
>
>
Sat, 2010-01-23, 20:17
#4
Re: Re: Accidentally catching NonLocalReturnException
I fully understand catching Exception, but catching Throwable means you'll be interfering with all kinds of Errors.
Perhaps it'd be better to have NonLocalReturnException (really all ControlFlow stuff) inherit from Throwable instead?
Viktor Klang
| "A complex system that works is invariably
| found to have evolved from a simple system
| that worked." - John Gall
Blog: klangism.blogspot.com
Twttr: twitter.com/viktorklang
Code: github.com/viktorklang
2010/1/23 Piotr Kołaczkowski <pkolaczk@elka.pw.edu.pl>
Perhaps it'd be better to have NonLocalReturnException (really all ControlFlow stuff) inherit from Throwable instead?
Viktor Klang
| "A complex system that works is invariably
| found to have evolved from a simple system
| that worked." - John Gall
Blog: klangism.blogspot.com
Twttr: twitter.com/viktorklang
Code: github.com/viktorklang
2010/1/23 Piotr Kołaczkowski <pkolaczk@elka.pw.edu.pl>
Viktor Klang pisze:
Catching Throwable is generally something to avoid.
Also, since Scala doesn't employ checked exceptions, I usually don't feel the need to wrap exceptions either.
Yes, I know, but sometimes you do not know which exceptions to expect from a module written by another programmer, so you end up catching Throwable just for safety that your module won't crash and logging it somewhere (this particular piece of code had to do with plugins developed by third parties). The wrapping was not for purpose of making checked exception unchecked as often is done in Java, but to tell the caller some more information about what caused the exception (which plugin, etc.).
And catching a NonLocalReturnException was a surprise :)
Regards,
Piotr Kołaczkowski
Cheers,
Viktor Klang
| "A complex system that works is invariably
| found to have evolved from a simple system
| that worked." - John Gall
Blog: klangism.blogspot.com <http://klangism.blogspot.com>
Twttr: twitter.com/viktorklang <http://twitter.com/viktorklang>
Code: github.com/viktorklang <http://github.com/viktorklang>
2010/1/23 Rex Kerr <ichoran@gmail.com <mailto:ichoran@gmail.com>>
That looks to me like a good workaround.
In general, returns (especially non-local ones like you've shown)
are not encouraged, as it makes understanding code flow more difficult.
If you can, consider using a functional alternative (though it
admittedly cannot cover all the same cases):
collection.iterator.takeWhile( /*condition */).foreach(x => /* code */)
(use elements instead of iterator in 2.7.x). Another
less-functional idea:
var collected = false;
val collection = /*...*/;
collection.find( x => {
try {
stuff
if (/*things are good*/) collected = true;
}
catch { stuff }
collected
} )
--Rex
2010/1/23 Piotr Kołaczkowski
<pkolaczk@elka.pw.edu.pl
<mailto:pkolaczk@elka.pw.edu.pl>>
Hello everyone,
I have a code:
def something(): Unit = {
val collection = ...
collection foreach x => {
try {
// ...
return
} catch {
case t:Throwable => doSomething(); throw new MyOwnException(t)
}
}
}
This breaks when return is executed. I know this return is
implemented by throwing a NonLocalReturnException and I should
not catch it. But how to handle such cases when I really, really
have to catch all exceptions? I work this around by rethrowing
NonLocalReturnException:
} catch {
case t:NonLocalReturnException => throw t
case t:Throwable => doSomething(); throw new MyOwnException(t)
}
Is it a good workaround, or is there something better recommended?
Anyway, are there chances that when Java 7 is released, the non
local return will be done by something faster than exceptions?
Regards,
Piotr
Sat, 2010-01-23, 20:17
#5
Re: Re: Accidentally catching NonLocalReturnException
On Sat, 2010-01-23 at 19:56 +0100, Viktor Klang wrote:
> I fully understand catching Exception, but catching Throwable means
> you'll be interfering with all kinds of Errors.
>
> Perhaps it'd be better to have NonLocalReturnException (really all
> ControlFlow stuff) inherit from Throwable instead?
Yeah, I still don't understand why it inherits from RuntimeException.
ControlFlow inherits from Throwable, but explicitly mentions that
subclasses can inherit from other exceptions, so it seems like it was
not _just_ oversight.
It would be nice if someone explained the reasoning.
Best,
Ismael
Sat, 2010-01-23, 20:37
#6
Re: Accidentally catching NonLocalReturnException
On Sat, 2010-01-23 at 18:14 +0100, Piotr Kołaczkowski wrote:
> Anyway, are there chances that when Java 7 is released, the non local
> return will be done by something faster than exceptions?
Exceptions are actually pretty fast if the stacktrace generated is
suppressed (which it is for control flow exceptions in Scala).
Ismael
Mon, 2010-01-25, 03:47
#7
Re: Accidentally catching NonLocalReturnException
You could also do, similarly:catch { case t: Throwable if !t.isInstanceOf[NonLocalReturnException] => ...}
2010/1/23 Piotr Kołaczkowski <pkolaczk@elka.pw.edu.pl>
2010/1/23 Piotr Kołaczkowski <pkolaczk@elka.pw.edu.pl>
Hello everyone,
I have a code:
def something(): Unit = {
val collection = ...
collection foreach x => {
try {
// ...
return
} catch {
case t:Throwable => doSomething(); throw new MyOwnException(t)
}
}
}
This breaks when return is executed. I know this return is implemented by throwing a NonLocalReturnException and I should not catch it. But how to handle such cases when I really, really have to catch all exceptions? I work this around by rethrowing NonLocalReturnException:
} catch {
case t:NonLocalReturnException => throw t
case t:Throwable => doSomething(); throw new MyOwnException(t)
}
Is it a good workaround, or is there something better recommended?
Anyway, are there chances that when Java 7 is released, the non local return will be done by something faster than exceptions?
Regards,
Piotr
Tue, 2010-01-26, 14:27
#8
Re: Re: Accidentally catching NonLocalReturnException
Coming from a shop where there was a lot of : catch(Thorwable t) { logger.handlerError(t) } in the code, I'd ask nicely to please be more disciminatory in your exception handling. Especially when it comes to OutOfMemory errors or whatnot. That kind of code will hopefully never make it to a production system....
The issue with ignoring exceptions is that you need to know you can ignore it. In some cases, ignoring major exceptions is ok. In others, you really need it to bubble out and down the entire application/reboot
- Josh
2010/1/23 Piotr Kołaczkowski <pkolaczk@elka.pw.edu.pl>
The issue with ignoring exceptions is that you need to know you can ignore it. In some cases, ignoring major exceptions is ok. In others, you really need it to bubble out and down the entire application/reboot
- Josh
2010/1/23 Piotr Kołaczkowski <pkolaczk@elka.pw.edu.pl>
Viktor Klang pisze:
Catching Throwable is generally something to avoid.
Also, since Scala doesn't employ checked exceptions, I usually don't feel the need to wrap exceptions either.
Yes, I know, but sometimes you do not know which exceptions to expect from a module written by another programmer, so you end up catching Throwable just for safety that your module won't crash and logging it somewhere (this particular piece of code had to do with plugins developed by third parties). The wrapping was not for purpose of making checked exception unchecked as often is done in Java, but to tell the caller some more information about what caused the exception (which plugin, etc.).
And catching a NonLocalReturnException was a surprise :)
Regards,
Piotr Kołaczkowski
Cheers,
Viktor Klang
| "A complex system that works is invariably
| found to have evolved from a simple system
| that worked." - John Gall
Blog: klangism.blogspot.com <http://klangism.blogspot.com>
Twttr: twitter.com/viktorklang <http://twitter.com/viktorklang>
Code: github.com/viktorklang <http://github.com/viktorklang>
2010/1/23 Rex Kerr <ichoran@gmail.com <mailto:ichoran@gmail.com>>
That looks to me like a good workaround.
In general, returns (especially non-local ones like you've shown)
are not encouraged, as it makes understanding code flow more difficult.
If you can, consider using a functional alternative (though it
admittedly cannot cover all the same cases):
collection.iterator.takeWhile( /*condition */).foreach(x => /* code */)
(use elements instead of iterator in 2.7.x). Another
less-functional idea:
var collected = false;
val collection = /*...*/;
collection.find( x => {
try {
stuff
if (/*things are good*/) collected = true;
}
catch { stuff }
collected
} )
--Rex
2010/1/23 Piotr Kołaczkowski
<pkolaczk@elka.pw.edu.pl
<mailto:pkolaczk@elka.pw.edu.pl>>
Hello everyone,
I have a code:
def something(): Unit = {
val collection = ...
collection foreach x => {
try {
// ...
return
} catch {
case t:Throwable => doSomething(); throw new MyOwnException(t)
}
}
}
This breaks when return is executed. I know this return is
implemented by throwing a NonLocalReturnException and I should
not catch it. But how to handle such cases when I really, really
have to catch all exceptions? I work this around by rethrowing
NonLocalReturnException:
} catch {
case t:NonLocalReturnException => throw t
case t:Throwable => doSomething(); throw new MyOwnException(t)
}
Is it a good workaround, or is there something better recommended?
Anyway, are there chances that when Java 7 is released, the non
local return will be done by something faster than exceptions?
Regards,
Piotr
Tue, 2010-01-26, 17:07
#9
Re: Accidentally catching NonLocalReturnException
The intent of the posted code was not to IGNORE exceptions completely,
but to isolate them. Nevertheless, terminating application in case of a
fatal error is the LAST thing users expect. In case of a plugin manager,
disabling a plugin that caused error on ANY unhandled Throwable and
continuing running the application is a much better solution than crashing.
Regards,
Piotr Kołaczkowski
Josh Suereth pisze:
> Coming from a shop where there was a lot of : catch(Thorwable t) {
> logger.handlerError(t) } in the code, I'd ask nicely to please be more
> disciminatory in your exception handling. Especially when it comes to
> OutOfMemory errors or whatnot. That kind of code will hopefully never
> make it to a production system....
>
> The issue with ignoring exceptions is that you need to know you can
> ignore it. In some cases, ignoring major exceptions is ok. In others,
> you really need it to bubble out and down the entire application/reboot
>
> - Josh
>
> 2010/1/23 Piotr Kołaczkowski >
>
> Viktor Klang pisze:
>
> Catching Throwable is generally something to avoid.
>
> Also, since Scala doesn't employ checked exceptions, I usually
> don't feel the need to wrap exceptions either.
>
>
> Yes, I know, but sometimes you do not know which exceptions to
> expect from a module written by another programmer, so you end up
> catching Throwable just for safety that your module won't crash and
> logging it somewhere (this particular piece of code had to do with
> plugins developed by third parties). The wrapping was not for
> purpose of making checked exception unchecked as often is done in
> Java, but to tell the caller some more information about what caused
> the exception (which plugin, etc.).
>
> And catching a NonLocalReturnException was a surprise :)
>
> Regards,
> Piotr Kołaczkowski
>
>
> Cheers,
>
> Viktor Klang
> | "A complex system that works is invariably
> | found to have evolved from a simple system
> | that worked." - John Gall
>
> Blog: klangism.blogspot.com
>
> Twttr: twitter.com/viktorklang
>
> Code: github.com/viktorklang
>
>
>
> 2010/1/23 Rex Kerr
>
> >>
>
>
> That looks to me like a good workaround.
>
> In general, returns (especially non-local ones like you've shown)
> are not encouraged, as it makes understanding code flow more
> difficult.
>
> If you can, consider using a functional alternative (though it
> admittedly cannot cover all the same cases):
>
> collection.iterator.takeWhile( /*condition */).foreach(x =>
> /* code */)
>
> (use elements instead of iterator in 2.7.x). Another
> less-functional idea:
>
> var collected = false;
> val collection = /*...*/;
> collection.find( x => {
> try {
> stuff
> if (/*things are good*/) collected = true;
> }
> catch { stuff }
> collected
> } )
>
> --Rex
>
> 2010/1/23 Piotr Kołaczkowski
>
> >>
>
>
> Hello everyone,
>
> I have a code:
>
>
> def something(): Unit = {
>
> val collection = ...
> collection foreach x => {
>
> try {
>
> // ...
> return
>
> } catch {
> case t:Throwable => doSomething(); throw new
> MyOwnException(t)
> }
> }
> }
>
>
> This breaks when return is executed. I know this return is
> implemented by throwing a NonLocalReturnException and I
> should
> not catch it. But how to handle such cases when I really,
> really
> have to catch all exceptions? I work this around by
> rethrowing
> NonLocalReturnException:
>
> } catch {
> case t:NonLocalReturnException => throw t
> case t:Throwable => doSomething(); throw new
> MyOwnException(t)
> }
>
>
> Is it a good workaround, or is there something better
> recommended?
> Anyway, are there chances that when Java 7 is released,
> the non
> local return will be done by something faster than
> exceptions?
>
> Regards,
> Piotr
>
>
>
>
>
Wed, 2010-01-27, 03:57
#10
Re: Re: Accidentally catching NonLocalReturnException
How do you propose to continue running the application in the face of an OutOfMemoryError?
--j
2010/1/26 Piotr Kołaczkowski <pkolaczk@elka.pw.edu.pl>
--j
2010/1/26 Piotr Kołaczkowski <pkolaczk@elka.pw.edu.pl>
The intent of the posted code was not to IGNORE exceptions completely, but to isolate them. Nevertheless, terminating application in case of a fatal error is the LAST thing users expect. In case of a plugin manager, disabling a plugin that caused error on ANY unhandled Throwable and continuing running the application is a much better solution than crashing.
Regards,
Piotr Kołaczkowski
Josh Suereth pisze:
Coming from a shop where there was a lot of : catch(Thorwable t) { logger.handlerError(t) } in the code, I'd ask nicely to please be more disciminatory in your exception handling. Especially when it comes to OutOfMemory errors or whatnot. That kind of code will hopefully never make it to a production system....
The issue with ignoring exceptions is that you need to know you can ignore it. In some cases, ignoring major exceptions is ok. In others, you really need it to bubble out and down the entire application/reboot
- Josh
2010/1/23 Piotr Kołaczkowski <pkolaczk@elka.pw.edu.pl <mailto:pkolaczk@elka.pw.edu.pl>>
Viktor Klang pisze:
Catching Throwable is generally something to avoid.
Also, since Scala doesn't employ checked exceptions, I usually
don't feel the need to wrap exceptions either.
Yes, I know, but sometimes you do not know which exceptions to
expect from a module written by another programmer, so you end up
catching Throwable just for safety that your module won't crash and
logging it somewhere (this particular piece of code had to do with
plugins developed by third parties). The wrapping was not for
purpose of making checked exception unchecked as often is done in
Java, but to tell the caller some more information about what caused
the exception (which plugin, etc.).
And catching a NonLocalReturnException was a surprise :)
Regards,
Piotr Kołaczkowski
Cheers,
Viktor Klang
| "A complex system that works is invariably
| found to have evolved from a simple system
| that worked." - John Gall
Blog: klangism.blogspot.com <http://klangism.blogspot.com>
<http://klangism.blogspot.com>
Twttr: twitter.com/viktorklang <http://twitter.com/viktorklang>
<http://twitter.com/viktorklang>
Code: github.com/viktorklang <http://github.com/viktorklang>
<http://github.com/viktorklang>
2010/1/23 Rex Kerr
<ichoran@gmail.com
<mailto:ichoran@gmail.com>
<mailto:ichoran@gmail.com
<mailto:ichoran@gmail.com>>>
That looks to me like a good workaround.
In general, returns (especially non-local ones like you've shown)
are not encouraged, as it makes understanding code flow more
difficult.
If you can, consider using a functional alternative (though it
admittedly cannot cover all the same cases):
collection.iterator.takeWhile( /*condition */).foreach(x =>
/* code */)
(use elements instead of iterator in 2.7.x). Another
less-functional idea:
var collected = false;
val collection = /*...*/;
collection.find( x => {
try {
stuff
if (/*things are good*/) collected = true;
}
catch { stuff }
collected
} )
--Rex
2010/1/23 Piotr Kołaczkowski
<pkolaczk@elka.pw.edu.pl
<mailto:pkolaczk@elka.pw.edu.pl>
<mailto:pkolaczk@elka.pw.edu.pl
<mailto:pkolaczk@elka.pw.edu.pl>>>
Hello everyone,
I have a code:
def something(): Unit = {
val collection = ...
collection foreach x => {
try {
// ...
return
} catch {
case t:Throwable => doSomething(); throw new
MyOwnException(t)
}
}
}
This breaks when return is executed. I know this return is
implemented by throwing a NonLocalReturnException and I
should
not catch it. But how to handle such cases when I really,
really
have to catch all exceptions? I work this around by
rethrowing
NonLocalReturnException:
} catch {
case t:NonLocalReturnException => throw t
case t:Throwable => doSomething(); throw new
MyOwnException(t)
}
Is it a good workaround, or is there something better
recommended?
Anyway, are there chances that when Java 7 is released,
the non
local return will be done by something faster than
exceptions?
Regards,
Piotr
Wed, 2010-01-27, 05:27
#11
Re: Re: Accidentally catching NonLocalReturnException
On Tuesday January 26 2010, Jorge Ortiz wrote:
> How do you propose to continue running the application in the face of
> an OutOfMemoryError?
It can be done, if you're careful. E.g., have a reserve buffer allocated
that you can release when memory is exhausted and you want to retain
control. I found this technique worked well enough when the the program
executes in isolation (as a separately launched, non-GUI command-line
application) and there's a well-defined portion of the code that is
susceptible to running out of memory. That portion is protected by
allocating the reserve buffer and surrounded by a try / catch for the
OOME.
Where I found that approach to be inadequate is in a shared environment
like a servlet container. In that case you have to use a pre-emptive
approach that trips an abort and cleanup procedure when free memory
falls below some threshold. I forget which API I used for that. Maybe
some JMX thing?
> --j
Randall Schulz
In general, returns (especially non-local ones like you've shown) are not encouraged, as it makes understanding code flow more difficult.
If you can, consider using a functional alternative (though it admittedly cannot cover all the same cases):
collection.iterator.takeWhile( /*condition */).foreach(x => /* code */)
(use elements instead of iterator in 2.7.x). Another less-functional idea:
var collected = false;
val collection = /*...*/;
collection.find( x => {
try {
stuff
if (/*things are good*/) collected = true;
}
catch { stuff }
collected
} )
--Rex
2010/1/23 Piotr Kołaczkowski <pkolaczk@elka.pw.edu.pl>