There are several types of error that T-SQL's TRY/CATCH won't catch at all (see below). Some of these are understandable (though I'd prefer for low-severity errors to also be caught, as they would be in application code), and some are unavoidable because errors that terminate the session don't even allow the CATCH to execute.
But why the limitation on compilation errors in the same scope? Is it impossible to handle or was it a deliberate decision? If the latter, what was the reasoning for it? Why can we catch compilation errors once they reach the parent scope, but not in the current scope?
Also, I wasn't around for the "good old days", but apparently it's possible to catch these using the old methods of error handling, so why not at least just handle it the same way under the hood?
Warnings or informational messages that have a severity of 10 or lower.
Errors that have a severity of 20 or higher that stop the SQL Server Database Engine task processing for the session. If an error occurs that has severity of 20 or higher and the database connection is not disrupted, TRY...CATCH will handle the error.
Attentions, such as client-interrupt requests or broken client connections.
When the session is ended by a system administrator by using the KILL statement.
The following types of errors are not handled by a CATCH block when they occur at the same level of execution as the TRY...CATCH construct:
Compile errors, such as syntax errors, that prevent a batch from running.
Errors that occur during statement-level recompilation, such as object name resolution errors that occur after compilation because of deferred name resolution.
Object name resolution errors
Related
I was looking at scala.util.control.NonFatal. I can't find the source, but I believe it is something like this.
They are declaring LinkageError as Fatal ...
Tomcat (at least last few years I used it) always returned 500 on catch Throwable, rather than crashing on certain kinds of errors. So do many other systems that make a best effort to always return something to the client.
So, my end question is when would you use NonFatal instead of making a best-effort attempt to provide some response?
As an example, now Futures in Twitter's Future library end up not resolving on NoSuchMethodError so my Future no longer resolves as failed with a Throwable but instead throw up the stack (differently from RuntimeException). In fact, in the open source Finagle stack, a NoSuchMethodError will cause the client socket connection to close on the client with no 500 http error back to customer. Customer then thinks 'hmm, network issue maybe ... why did my socket close'
So far, it has caused me nothing but issues and I admit to be a little frustrated, but need to be open to more use cases. For years, KISS and treating every Throwable in the catchall as non fatal has worked, but NonFatal is implying there are use-cases where we should do something different.
The source code of NonFatal is linked from the API docs.
Fatal errors are those from which your system or the JVM will most likely not recover correctly, so catching those errors is not a good idea.
The sub-classes of LinkageError are: ClassCircularityError, ClassFormatError, ExceptionInInitializerError, IncompatibleClassChangeError, NoClassDefFoundError, UnsatisfiedLinkError, VerifyError. These all occur when your class path is broken, there are invalid or binary incompatible class files. It's safe to assume that your entire system is broken if these happen at runtime.
To answer the question: You should "let it crash". Always use a NonFatal pattern match when you need a catch-all clause. It will also do you the favour and handle control-flow related exceptions correctly (e.g. NonLocalReturnControl).
Note that unlike the old source you link to, StackOverflowError is not non-fatal any longer, the decision was revised in Scala 2.11 as per SI-7999.
I got the following runtime error:
2014-12-10 19:26:39.695 Bliss2[21855:994070] Error: object not found for update (Code: 101, Version: 1.5.0)
I assume the [21855:994070] has a meaning.
How do I use it to track down the error in the code?
That is not a "runtime error". It is an NSLog message and has been executed and logged in perfectly good order (e.g. by some third-party code you are using?). Of course the code may then have thrown an exception / aborted, but if it did (and I don't know whether it did), that has nothing to do with the log message itself, except that you're being told first that there's a problem, apparently as a courtesy.
As for the numbers, they probably have nothing to say that will concern you here. The first number is your process number and won't be stable between invocations; it is rarely of interest. The second number is the thread number and is of interest when there are many log statements for discovering whether this log statement is executed in a background thread (or in the same thread as other log statements).
AFAIK when some errors were reported from within one processor, other will not be run.
Is there any way to force processing independently?
According to the documentation, only uncaught errors or exceptions stop further processing:
If a processor throws an uncaught exception, the tool may cease other active annotation processors. [...] Since annotation processors are run in a cooperative environment, a processor should throw an uncaught exception only in situations where no error recovery or reporting is feasible.
If a processor reports an error, the errorRaised() method should return true in the next round but not stop processing:
Printing a message with an error kind will raise an error.
If a processor raises an error, the current round will run to completion and the subsequent round will indicate an error was raised.
It says "the tool may cease other active annotation processors" (emphasis added). So if you need to keep going on even in case of uncaught exceptions, it should be possible with the right processing tool. I don't know if there are any tools that support this though. At least the processing tool should be the direction to look for if you need this feature.
Many of the Caché API methods return a %Status object which indicates if this is an error. The thing is, when it's an unknown error I don't know how to handle (like a network failure) what I really want to do is "throw" the error so my code stops what it's doing and the error gets caught by some higher level error handler (and/or the built-in %ETN error log).
I could use ztrap like:
s status = someObject.someMethod()
ztrap:$$$ISERR(status)
But that doesn't report much detail (unlike, say, .NET where I can throw an exception all the way to to the top of the stack) and I'm wondering if there are any better ways to do this.
Take a look at the Class Reference for %Exception.StatusException. You can create an exception from your status and throw it to whatever error trap is active at the time (so the flow of control would be the same as your ZTRAP example), like this
set sc = someobj.MethodReturningStatus()
if $$$ISERR(sc) {
set exception = ##class(%Exception.StatusException).CreateFromStatus(sc)
throw exception
}
However, in order to recover the exception information inside the error trap code that catches this exception, the error trap must have been established with try/catch. The older error handlers, $ztrap and $etrap, do not provide you with the exception object and you will only see that you have a <NOCATCH> error as the $ZERROR value. Even in that case, the flow of control will work as you want it to, but without try/catch, you would be no better off than you are with ZTRAP
These are two different error mechanisms and can't be combined in this way. ztrap and %ETN are for Cache level errors (the angle bracket errors like <UNDEFINED>). %Status objects are for application level errors (including errors that occurred through the use of the Cache Class Library) and you can choose how you want to handle them yourself. It's not really meaningful to handle a bad %Status through the Cache error mechanism because no Cache error has occurred.
Generally what most people do is something akin to:
d:$$$ISERR(status) $$$SomeMacroRelevantToMyAppThatWillHandleThisStatus(status)
It is possible to create your own domain with your own whole host of %Status codes with attendant %msg values for your application. Your app might have tried to connect to an FTP server and had a bad password, but that doesn't throw a <DISCONNECT> and there is no reason to investigate the stack, just an application level error that needs to be handled, possibly by asking the user to enter a new password.
It might seem odd that there are these two parallel error mechanisms, but they are describing two different types of errors. Think of one of them being "platform" level errors, and the other as "application level errors"
Edit: One thing I forgot, try DecomposeStatus^%apiOBJ(status) or ##class(%Status).LogicalToOdbc(status) to convert the status object to a human readable string. Also, if you're doing command line debugging or just want to print the readable form to the principal device, you can use $system.OBJ.DisplayError(status).
Apologies if this question has already been answered somewhere else, but I could not find any decisive answer when searching on it:
I'm wondering when try-catch blocks are to be used in objective-c iPhone applications. Apple's "Introduction to the Objective-C Programming Language" state that exceptions are resource intensive and that one should "not use exceptions for general flow-control, or simply to signify errors." From reading a few related questions here I also gather that people are not often using this method in practice.
So I guess the question is: what are the situations when it's appropriate to use try-catch blocks when developing for iPhone/Objective-C and when should they absolutely NOT be used?
For example, I could use them to catch beyond bounds and other exceptions when working with objects in arrays. I have a method which performs are few tasks with objects that are passed on in a number of arrays. The method returns nil if an error has occurred and a try-catch block could help me catch exceptions. However, I could of course simply write little if-tests here and there to ensure that I, for instance, never try to access an index beyond an arrays bounds. What would you do in this situation?
Thanks a lot!
It is only appropriate to use #try/#catch to deal with unrecoverable errors. It is never appropriate to use #throw/#try/#catch to do control-flow like operations.
In particular, it would not be appropriate to use for catching out-of-bounds exceptions unless your goal is to catch them and somehow report the error, then -- typically -- crash or, at the least, warn the user that your app is in an inconsistent state and may lose data.
Behavior of any exception thrown through system framework code is undefined.
Your if-test to do bounds checking is a far more appropriate solution.
#bbum's answer is absolutely correct (and he would know the answer better than most). To elaborate a bit...
In Cocoa, you should generally avoid using exceptions (#try/#catch[/#finally]) for flow control. As you mention, exceptions carry an unusually large cost (compared to run-times such as JVM or the CLR optimized for exception use). Furthermore, most of the Cocoa frameworks are not exception safe. Thus, throwing an exception through Cocoa framework code is dangerous and will likely cause odd, difficult to diagnose, and catastrophic (think possible data loss) bugs in your app.
Instead of using exceptions, Cocoa code uses NSError to signal error conditions that are recoverable within the application. Exceptions are used to signal conditions from which your application cannot recover. Thus a UI component requesting an out-of-bounds position in a model array could be signaled with an error (presented to the user with a reason their request could not be completed) while attempting to access an out-of-bounds position given an index that you think should be valid signals an exceptional condition where you app is in an inconsistent state and should probably die as soon as possible before it can do more damage.
NSParameterAssert, for example signals with an NSException when an assertion fails.
So when should you use exceptions or #try/#catch? If you're using a C/C++ library that makes use of exceptions, you should catch those exceptions before they can get thrown back through Cocoa code. Similarly, if you are serious about consistency of state within your application, you should raise an exception as soon as you detect that your state is inconsistent (and unrecoverable).