Catching Throwable in Blackberry Java: Good Idea? - blackberry

I often see catch clauses for Throwable in Blackberry documentation, such as the Network API docs. My sense is that this is not generally a good practice in Java.
Is there a reason for this in Blackberry programming?
Does it have to do with stack trace generation for Throwables?

When you catch Throwable in a BlackBerry app, not only does it preserve the stack trace, it saves that stack trace in the device event log. There is no way for an app to get a stack trace itself, so unfortunately you can't automatically collect stack traces.
To view the stack trace, you pull up the event log viewer. For blackberries with physical keyboards, hold 'Alt' and then press L G L G to bring up the event log.

Read the documentation for java.lang.Error, which is a subclass of Throwable, and you'll see the problem with catching Throwable.
It says:
An Error is a subclass of Throwable
that indicates serious problems that a reasonable application
should not try to catch.
For example, you could end up inadvertently catching a VirtualMachineError indicating the whole VM is in a broken state. Putting something in the finally block to run on broken VM doesn't seem like a good idea.

I don't think there's a special reason. See the comment:
} catch (Throwable t) { // can also catch specific exceptions to include special hadling for the different types
It means the example is basic. And has a typo, and a bad practice. So catch specific exceptions if possible.

On the BB platform, if Throwable is caught it preserves the stacktrace and usually renders it on the screen, blasting in the user's face. Not very good for UX :(
When Exception (and extended classes) are caught the stacktrace is thrown away for efficiency reasons.

Related

Uncaught exception handler on iOS for particular threads

For metric collection threads, we want them to never crash the app. For crashes from those threads, we want catch them and report to the server without crashing the app.
On Android or Java based app, we can set uncaught exception handler for a particular thread or a thread group. See the following example.
Is there similar mechanism on iOS platform for Objective runtime level uncaught exceptions? Is there any example code as reference?
val pipelineThread = Thread({
try {
intArrayOf(1, 2, 3, 4, 5).asList()
.parallelStream()
.map { e ->
e + 1
}.map {
throw RuntimeException("Pipeline map error.")
}.collect(Collectors.toList())
} catch (e: RuntimeException) {
// Exceptions thrown from pipeline will be handled in the same way
// as regular statements, even if it is parallel stream.
throw StreamPipelineException("Java parallel stream.", e)
}
}, "PipelineThread")
with(pipelineThread) {
setUncaughtExceptionHandler { p0, p1 ->
assert(p0.name.contentEquals("PipelineThread"))
assert(p1 is StreamPipelineException)
assert(p1.cause is RuntimeException)
assert(p1.message.contentEquals("Java parallel stream."))
}
}
I only find the top-level handler setting method.
For metric collection threads, we want them to never crash the app.
On Mac, you should move those threads into a separate process. This is how web browsers ensure that bugs impacting one tab do not impact other tabs or crash the whole browser. Usually the best tool for communicating between those processes is XPC.
On iOS, you will need to write your metric collection code carefully to avoid mistakes and not crash. You cannot spawn other processes directly in iOS today. (I keep hoping some day it will be possible. The OS can handle it. Third-party apps just aren't allowed to.)
NSSetUncaughtExceptionHandler is not intended to prevent crashes. It just gives a mechanism to record a little data or clean up certain things before crashing. Even in those cases, it must be used extremely carefully, since the system is in an undefined state during an uncaught exception. While in principle it's possible to write exception-safe Objective-C, the core frameworks are generally not. After raising an exception, there is no promise what state the system is in, and preconditions may be violated. As the docs note:
The Cocoa frameworks are generally not exception-safe. The general pattern is that exceptions are reserved for programmer error only, and the program catching such an exception should quit soon afterwards.
Assuming you're using NSThread or NSOperation for your "metric collection threads," you can create something similar to Java's approach using this, but I don't recommend it:
- (void)main {
#try {
... your code ...
} #catch ( NSException *e ) {
// Handle the exception and end the thread/operation
}
}
I don't recommend this because it can create difficult-to-solve bugs in distant parts of the program because the frameworks are not exception-safe. But I've seen it in enough production code to know it often works well enough. You have to decide if "app crashes and user relaunches it" is worse than "app doesn't crash but now behaves kind of weird and maybe corrupts some user data, but maybe doesn't."
But many Objective-C crashes are not due to exceptions in any case. They are due to signals, most commonly because of memory violations. In this case, the system is in an even less stable state. Even allocating or releasing memory may be invalid. (I once made the mistake of allocating memory in a signal handler, and deadlocked the program in a tight busy-loop. The Mac actually got hot. It would have been better to have just crashed.) For more, see How to prevent EXC_BAD_ACCESS from crashing an app?
Java incurs a lot of overhead, including a full virtual machine and extra bounds checks, to make it possible to catch the vast majority of error conditions (even ones you can't really recover from). It's a trade-off. It's still possible to have Java code that is not exception-safe and can fail to work correctly once an exception has been thrown, and it sometimes would be nice if Java would just crash and show you where the error is rather than programmers quietly swallowing the errors... but that's a different rant. Sometimes the sandbox makes things very nice.
Objective-C is built directly on C and allows accessing raw memory. If you do that incorrectly, it's undefined behavior and just about anything can happen, though usually the OS will kill the program. So even though it's possible to catch some kinds of exceptions, you cannot prevent all crashes.

Delphi effective way to handle socket error [duplicate]

I've set Application.OnException to a custom exception handler so that I can log crashes and give an option to exit. However, I'm now finding that this runs even on exceptions that I've already handled, for instance, exceptions that come up when validating number inputs. Is there a way to have the custom exception handler only run on unhandled exceptions?
Edit: it turns out that I get the expected behavior when I run outside the debugger. Maybe it's just a debugger thing. I do not find the Delphi debugger's interaction with exceptions to be intuitive, to say the least.
If behavior changes inside and outside the debugger, then it's not really your program that's telling you about exceptions. I've written about this phenomenon on my Web site:
Why do I continue getting error messages even after I have written an exception handler?
An excerpt:
In its default settings, the Delphi IDE notifies you whenever an exception occurs in your program ... . What’s important to realize is that at that point, none of your program’s exception-handling code has run yet. It’s all Delphi itself; its special status as a debugger allows it to get first notification of any exception in your program, even before your program knows about it.
After you dismiss Delphi’s message box, execution will be paused at the best line of your source code Delphi could find to represent the source of the exception. Press the “Run” button to have your program resume. Control will pass to the next finally or except
block. Before you resume your program, you may use the various debugging tools at your disposal. You can inspect the values of any variables in scope, and you can even modify their values.
So, how do you notify Delphi that you've already handled an exception? You don't — because your program hasn't handled it yet. And why can't the debugger detect whether your program is going to handle an exception? Because in order to do that, it needs to execute your program further. Detecting the lack of an exception handler is like solving the halting problem. The only way to determine whether an exception is going to be handled is to let the program run and then see whether the exception gets handled. But by that point, it's too late to do any debugging, so the debugger has no choice but to pause your program when it first detects an exception and then let you figure out what to do from there.
My article goes on to describe some ways you can avoid having the debugger catch certain exceptions, summarized here:
Use advanced breakpoints to temporarily disable breaking on exceptions for certain regions of the code.
Configure the debugger to ignore certain classes of exceptions (and their descendants).
Tell the debugger not to notify you about any exceptions.
Disable integrated debugging altogether.
There's another options that I didn't include in my article:
Change your program such that the exception doesn't get raised in the first place.
You say you're validating numeric input. That sounds to me like you're doing something like calling StrToInt and then catching the EConvertError exception when the input isn't a valid integer. That's an expensive way of validating input. Instead of that, use TryStrToInt, which will tell you whether the conversion succeeded, or StrToIntDef, which will silently return a default value instead of raising an exception. Another option is plain old Val, which tries to convert a string, and if it fails, it tells you which position in the string caused the failure. Val is particularly useful if you want to consume as many characters as possible for the conversion and then resume parsing at the next non-numeric character.
Quoting from the documentation (Delphi 7) on TApplication.OnException
"Use OnException to change the default behavior that occurs when an exception is not
handled by application code."
So: Only unhandled exception will be available in the OnException event handler. What you are experiencing is probably the Delphi IDE breaking on the exception. This is (at least in Delphi 7) configurable.
In Delphi 7 you can configure it by clicking on the Tools->Debugger Options menu. Then select the "Language Exceptions" an un-ckech the "Stop on Delphi exceptions" checkbox. It might however be different in other delphi versions.
An alternative might be to not use Application.OnException. But to simply catch all exceptions in your "main" function. That way you can catch all exceptions you have not cached before, log the exception, and then crash.
Application.OnException should only fire for unhandled exceptions. Re-raising an exception in a try-except block will cause the exception to be handled by Application.OnException. For input validation that raises an exception, you could display a message to the user and then re-raise the exception only if you want it recorded into the error log.

What's the deal with catching exceptions?

So I've read a lot about catching exceptions. Let's talk about this and iOS together. I've used it with Google Analytics to submit information about the crash and using that to fix bugs.
But this raises a question. Can catching these exceptions help prevent apps from crashing. Can you theoretically prevent that bit of code from crashing the app and keep the app open. Now I get the fact that it would probably be impossible to do if there was no memory to be used but it would still be nice to know about.
Sorry if this sounds like a stupid questions and I really should read more about it and do some more research. Any information would be helpful.
I do have a fairly decent knowledge of iOS obj-c for my age and am willing to look into what you have to say.
Thanks!
Exceptions on iOS should never be caught; they are fatal for a reason. Unlike most languages that have a rich exception hierarchy and multiple means of throwing/catching exceptions for the benefit of the program as a whole, Cocoa-Touch code is built around the principle that all exceptions are fatal. It is a mistake to think that you can catch an exception thrown through any frames of Apple-provided code and have your process continue unhindered. It is an even more grave mistake to catch and rethrow the exception for the purpose of logging.
The exceptions thrown by Cocoa-Touch indicate serious errors in program logic, or undefined and unresolvable state in an object. It is not OK to ignore them, or log them after catching them. They must be fixed and prevented from being thrown in the first place in order to truly guarantee your process remains stable.

Error vs. Exception in Dart

Why are there Errors AND Exceptions in Dart and not either Errors OR Exceptions?
Is the reason a historical one oder what?
I can throw an Error, I can throw an Exception. None of them is checked by the Analyzer like in Java (Exception vs. RuntimeException)
From this post, quoting Bob Nystrom:
Error and its subclasses are for programmatic errors. If one of those
occurs, your code is bad and you should fix your code.
Non-Error exception classes are for runtime errors. Sometimes you can
prevent them from being thrown, but often you cannot.
Except in a few special circumstances, idiomatic Dart should throw
Errors, but never catch them. They exists specifically to not be
caught so that they take down the app and alert the programmer to the
location of the bug.
In other words, you should expect (and check for) exceptions (it is intended that you should handle them). If you get an error, then you need to check how you're using the API that's throwing the error - you're probably using it wrong.
If you're writing an API, then you should use the same pattern. Errors are messages to downstream developers about how they are using your API.
Exception
An Exception in Dart should be thrown for regular, expected program flow and is intended to be caught:
An Exception is intended to convey information to the user about a failure, so that the error can be addressed programmatically. It is intended to be caught, and it should contain useful data fields.
Example: TimeoutException
A TimeoutException will be thrown "when a scheduled timeout happens while waiting for an async result", which is expected program flow.
If we have a download task for example and that download task is not finished after our specified timeout time of thirty seconds (which can happen), we want to communicate that to our user, hence, we need to catch the Exception.
Error
An Error in Dart should be thrown for unexpected program flow and should not be caught but addressed by the programmer:
An Error object represents a program failure that the programmer should have avoided.
Example: AssertionError
An AssertionError is thrown "when an assert statement fails", i.e. it should never happen because we assert that it should not.
If we see such an error, it means that we should change our code and we should definitely not catch the error.
In practice you can catch Errors, but you should not. There is a linter rule to help enforce that.
The fact that Dart allows it can still be useful, e.g. when testing assertions or other errors.
See this answer for a complete example scenario.
Exceptions are considered conditions that you can plan ahead for and catch.
Errors are conditions that you don't expect or plan for.
For more detailed ans
Thanks to Chris and from here
Exceptions should be used when there is a problem that is expected. A common one is any type of I/O operation (like network traffic), where the socket closes early, and trying to write data to that socket fails.
Errors occur when there is a problem that was not expected. Things like null pointers (you expected this variable to not be null), running our of memory, etc... When you try to use the API in a wrong way or stuffs like that.
For the most part you, as an app developer, will always use exceptions. Errors tend to be reserved for unexpected and fatal problems.

How can I find out which exceptions a Delphi function might throw?

Is there a good way to find out which exceptions a procedure/function can raise in Delphi (including it's called procedures/functions)?
In Java you always have to declare which exceptions that can be thrown, but this is not the case in Delphi, which could lead to unhandled exceptions.
Are there any code analysis tools that detects unhandled exceptions?
(Edit: It is now obvious that the question referred only to design-time checking.)
New answer:
I cannot state whether there are any tools to check this for you. Pascal Analyzer, for one, does not.
I can tell you, however, that in most Delphi applications, even if there was a tool to check this for you, you would get no results.
Why? Because the main message loop in TApplication.Run() wraps all HandleMessage() calls in an exception handling block, which catches all exception types. Thus you will have implicit/default exception handling around 99.999% of code in most applications. And in most applications, this exception handling will be around 100% of your own code - the 0.001% of code which is not wrapped in exception handling will be the automatically generated code.
If there was a tool available to check this for you, you would need to rewrite Application.run() such that it does not include exception handling.
(Previous answer:
The Application.OnException event handler can be assigned to catch all exceptions that aren't handled by other exception handlers. Whilst this is run-time, and thus perhaps not exactly what you are after (it sounds like you want to identify them at design time), it does allow you to trap any exception not handled elsewhere. In conjunction with tools such as the JCLDebug stuff in the Jedi Code Library, you could log a stack trace to find out where & why an exception occurred, which would allow for further investigation and adding specific exception handling or prevention around the guilty code...)
My guess is that you're trying to make Delphi behave like Java, which is not a good approach. I'd advise not to worry too much about unhandled exceptions. In the worst case, they'll bubble up to the generic VCL exception handler and cause a Windows message dialog. In a normal application, they won't halt the application.
Well-written code would document the different exceptions that can be raised so you can handle them in a meaningful way. Catch-all handlers aren't recommended since there is really no way to know what to do if you don't know why an exception was raised. I can also highly recommend madExcept.
Except for a scan on the "raise" keyword, there's no language construct in Delphi that tells the casual reader which exceptions can be expected from a method.
At runtime, one could add a catch-all exception handler in every method, but that's not advisable, as it will slow down the speed of execution. (And it's cumbersome to do too).
Adding an exception-handling block to a method will add a few assembly instructions to it (even when the exception isn't triggered), which forms measureable slow-down when the method is called very often.
There do exist a few libraries that can help you in analyzing runtime exceptions, like madExcept, JclDebug, and EurekaLog. These tools can log all kinds of details about the exception, it's highly advisable to use one of those!
The short answers is there is no tool that does what you say, and even a scan for the raise keyword wouldn't get you there. EAccessViolation or EOutOfMemory are just two of a number of exceptions that could get raised just about anywhere.
One fundamental thing about Delphi is the exceptions are hierarchical: All defined language exceptions descend from Exception, although it is worth noting that it is actually possible to raise any TObject descendant.
If you want to catch every exception that is raised in a particular procedure, just wrap it in a try / except block, but as was mentioned this is not recommended.
// Other code . . .
try
SomeProcedure()
except // BAD IDEA!
ShowMessage('I caught them all!');
end;
That will catch everything, even instances of a raised TObject. Although I would argue that this is rarely the best course of action. Usually you want to use a try / finally block and then allow your global exception handler (or one final try / except block) to actually handle the exceptions.
I will second (or is it third) MadExcept. I have been using it successfully in several commercial applications without any problems. The nice thing about MadExcept is that it will generate a report for you with a full stack trace that will generally point you in the right direction as to what went wrong, and can even include a screenshot, as well has have this automatically emailed to you from the clients computer with a simple mouse click.
However, you don't want to use this for ALL exceptions, just to catch the ones you miss. For instance, if you open a database and the login fails, it would be better for you to catch and handle this one yourself rather than give the user the MadExcept default error in your application occured message.
Any exception not explicitly or generally handled at a specific level will trickle upwards in the call stack. The Delphi RTL (Run Time Library) will generate a set of different exception classes - (mathematical errors, access errors, class specific errors etc). You can chose to handle them specifically or generally in the different try except blocks.
You don't really need to declare any new exception classes unless you need to propagate a specific functional context with the exception.
As previous commenters wrote, you can also add a mother of all exception handlers like MadExcept or EurekaLog to catch the uncaught.
edit: This is a blanket insurance against unhandled exceptions
try
ThisFunctionMayFail;
except
// but it sure won't crash the application
on e:exception
do begin
// something sensible to handle the error
// or perhaps log and/or display the the generic e.description message
end
end;
Take a look at http://www.madshi.net/madExceptDescription.htm
For runtime try Eurekalog. I do not know whether a tool exists for design time. You will have more dificoulties even when you have third party code without source. There is no need in Delphi to catch exceptions, so you do not have to declare them like in Java.
What I wanted to say is that Delphi does not require that an exception is handled. It will just terminate the program. EurekaLog provides means to log handled and unhandled exceptions and provide a wealth of information on the sate of the program when the exception occured, including the line of code it occured at and the call stack at the time.
As Jim McKeeth points out, you can't get a definitive answer, but it seems to me that one could partially answer the question by some static analysis: given a particular function/procedure, construct a call graph. Check each of the functions in that call graph for a raise statement. That would tell you, for instance, that TIdTcpClient.ReadString can raise an EIdNotConnected (among others).
A clever analyser might also note that some code uses the / operator and include EDivByZero as a possibility, or that some procedure accesses an array and include ERangeError.
That answer's a bit tighter than simply grepping for "raise".
Finalization sections of units can raise exceptions too. These will slip by I think... and are also somewhat problematic.
I think Delphi IDE has a build-in "stack trace" or "stack tree" something like.
This question reminds me of Skybuck's TRussianRoulette game... google it, it's code and answer may help.

Resources