How does one catch a custom exception with try-catch in cfscript?
<cffunction name="myFunction">
<cfset foo = 1>
<cfif foo EQ 1>
<cfthrow type="customExcp" message="FAIL!">
</cfif>
</cfif>
The try-catch is in cfscript. What should go into the catch() statement?
try {
myFunction();
} catch () {
writeOutput("Ooops");
}
James has pointed you to the docs in his answer, but he's missed the bit about you asking about custom exceptions. The syntax is:
try {
myFunction();
} catch (customExcp e) {
writeOutput("Ooops");
writeDump(e); // have a look at the contents of this
}
Note you can have as many catch blocks as you like, for different exception types. Any exception type not explicitly caught will still be thrown.
Related
I know that you can catch "all exceptions" and print the exception by
try
{
//some code...
}catch(const std::exception& e) {
cout << e.what();
}
but this is just for exceptions derived from std::exception.
I was wondering if there is a way to get some information from an ellipsis catch
try
{
//some code...
}catch(...) {
// ??
}
If the mechanism is the same as ellipsis for functions then I should be able to do something like casting the argument of the va_list and trying to call the what() method.
I haven't tried it yet but if someone knows the way I'd be excited to know how.
From C++11 and onwards, you can use std::current_exception &c:
std::exception_ptr p;
try {
} catch(...) {
p = std::current_exception();
}
You can then "inspect" p by taking casts &c.
In earlier standards there is no portable way of inspecting the exception at a catch(...) site.
Sorry, you can't do that. You can only access the exception object in a catch block for a specific exception type.
In this case, I have want to perform some actions based on the exception thrown and then re-throw the exception. Is this recommended - My aim is to do some work based on the exception thrown and rethrow it and have the application crash and generate dump that have the call stack in the exception.
class Foo
{
public:
void HandleException(const std::exception& ex)
{
// Log, report some metrics
throw;
}
void Work(//Some inputs)
{
try
{
// trying doing some work
}
catch (const std::exception& ex)
{
// This is really an exceptional situation, and the exception should be thrown which
// cause the exe to abort and create dump.
// Intention is to preserve call stack and have it in dump.
HandleException(ex);
}
}
}
Let me add another note to the question: When I have HandleException as a lambda function, throw in the lambda causes exception. Do I need to capture some state and how do I do that ?
When you catch an exception you have two options:
Achieve the original goal (contract) in some way, e.g. by retrying.
Report failure by throwing.
Rethrowing the original exception is one way to implement the second bullet point.
Yes that is valid. BUT it is also dangerous.
If you call throw; with no parameters and there is no exception currently in flight this will result in a call to std::terminate(). The problem with your current code is that anybody can call the function even when they are not in a catch block (which would result in termination).
So you may want to validate that an exception is propogating:
void HandleException(const std::exception& ex)
{
// Log, report some metrics
if (std::uncaught_exception()) {
throw;
}
// Maybe put an else here.
}
Also worth reading: GotW #47: Uncaught Exceptions
I wanted to know what header is required to catch std::unexpected exception. I am currently doing something like this. I would like the breakpoint of std::unexpected catcher to be hit. I am using VS2012
#include <iostream>
#include <exception>
void myfunction () throw (int)
{
throw "ABC";
}
int main()
{
try
{
myfunction();
}
catch(std::exception &f)
{
//breakpoint
}
catch( std::unexpected &f)
{
//breakpoint
}
}
When i try to build this code I get the error
"Error 2 error C2061: syntax error : identifier 'unexpected'
Am i missing a header ?
Update :
I realize now that std::unexpected is a function. So from what I understand is that if myfunction throws anything other than an int then std::unexpected method is called which defaults to terminate. So my question now becomes if I add the exception handler catch( ...) to the above code the breakpoint in catch( ...) is called. Which exception is that ? Does this catch std::unexpected exceptions ?
std::unexpected is called (yes, it is a function) when a function throws an exception whose type isn't listed in the dynamic exception specification. What you could do is use std::set_unexpected to register a handler that will be called.
#include <iostream>
#include <exception>
void myfunction () throw (int)
{
throw "Lol";
}
int main ()
{
std::set_unexpected ([] {std::cerr << "Unexpected stuff!"; throw 0; });
try
{
myfunction();
}
catch (int) { std::cerr << "caught int\n"; }
catch (...) { std::cerr << "caught some other exception type\n"; }
}
Note that both dynamic exception specifications and std::unexpected/std::set_unexpected became deprecated with C++11.
Updated part:
So my question now becomes if I add the exception handler catch(...)
to the above code the breakpoint in catch(...) is called.
That depends on where you put that handler. Putting it into main wont help - std::terminate will still get called. Putting it into myfunction would work but make the exception specification pointless.
Which exception is that ? Does this catch std::unexpected exceptions ?
catch(...) doesn't do magic. It simply matches every exception type, just as a variadic function (with an ellipse in the parameter-clause) can take every argument type*. It isn't different from the other handlers at all when it comes to unexpected exceptions.
* The slight difference is that catch(...) can catch non-POD-types without invoking undefined behavior.
Loopunroller's answer is correct as far as the C++ standard is concerned, but Visual C++'s implementation of dynamic exception specifications is utterly nonconforming - that is, it does not behave in the way specified in the C++ standard at all.
As explained in their documentation, dynamic exception specifications behaves like this in Visual C++:
no specification or throw (...): function can throw anything
throw (<nonempty-list-of-types>): function can throw anything, including things not in the list
throw (): function can't throw.
Microsoft's compiler generates code for a throw() function on the assumption that it doesn't throw. If it ends up throwing, std::unexpected() is not called, the program will simply behave incorrectly.
This is why your catch(...) in main() ended up catching the exception thrown from myfunction (and why unexpected() isn't called). Basically, in Microsoft's world, the throw (int) specification you attached to myfunction is about as meaningful as whitespace.
I tried googling ... but as expected, google ignored it.
I have this code :
try {
// some code
}
catch( ... ) {
// catch logic
}
I'm guessing that ... means any kind of exceptions, am I right ?
any other usages for this ?
I am aware of three use cases:
Variable number of arguments like 'printf(const char* fmt, ...)'
A catch anything as 'catch(...)'
A variadic template like 'template < typename ...T >' and unpacking 'T ...' (c++11)
And another one, which I missed, is preprocessing: variadic macros
Yes you are correct, catch(...) means to catch all the exceptions. However it is a good practice to catch exceptions by const reference. Like
catch(std::exception const & ex)
{
//code here
}
From MSDN remarks section:
Remarks:-
The code after the try clause is the guarded section of code. The
throw expression throws (raises) an exception. The code block after
the catch clause is the exception handler, and catches (handles) the
exception thrown by the throw expression if the type in the throw and
catch expressions are compatible. For a list of rules that govern
type-matching in catch blocks, see _. If the catch statement
specifies an ellipsis (...) rather than a type, the catch block
handles any type of exception, including C exceptions and system- or
application-generated exceptions such as memory protection, divide by
zero, and floating-point violations. Because catch blocks are tried in
program order, such a handler must be the last handler for its try
block. Use catch (…) with caution; typically such a catch block is
used to log errors and perform any special cleanup prior to stopping
program execution. Do not allow a program to continue unless the catch block knows how to >handle the specific exception that is caught.
try {
throw CSomeOtherException();
}
catch(...) { // Catch all exceptions – dangerous!!!
// Respond (perhaps only partially) to exception
throw; // Pass exception to some other handler
}
any other usages for this ?
One which I have seen is the usage in variable number of arguments like 'printf(const char* x, ...)'
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Difference between try-catch syntax for function
What is the difference in the utility and behavior of these try-catch blocks? When would I prefer one form over the other?
int f() {
try {
...
} catch(...) {
...
}
}
int f() try {
...
} catch (...) {
...
}
If the entire body must go into the exception block, I tend to prefer the 2nd form as it's easier to read (e.g. one less indentation level).
However, the main place where this makes a difference is in constructors. Consider:
Foo::Foo ()
try : member_with_throwing_constructor(initial_value)
{
}
catch ( ... )
{
// will process exceptions thrown by `member_with_throwing_constructor`
// this will be added by the compiler if you
// don't finish by a `throw ...` statement.
throw;
}
and
Foo::Foo ()
: member_with_throwing_constructor(initial_value)
{
try
{
}
catch ( ... )
{
// does not catch exceptions thrown in constructor
// of `member_with_throwing_constructor`.
}
// can keep processing if `catch` handler does not `return` or `throw`.
}
These two code snippets have radically different behavior. The first one will catch exceptions raised in data member constructors (usually through the initializer list, but default constructors apply too) and will automatically re-raise the exception because the instance could not be created safely. The second form does not cover data member initialization and allows you to choose whether to keep the object or not.
I also like to add a global try-catch in main() to help with debugging uncaught exceptions. The following snippet:
int main ( int, char ** )
try
{
// main program...
}
catch ( const std::exception& error )
{
std::cerr << "Uncaught exception: '" << error << "'." << std::endl;
return (EXIT_FAILURE);
}
catch ( ... )
{
std::cerr << "Uncaught exception of unknown type." << std::endl;
return (EXIT_FAILURE);
}
Some people will argue that not catching the exceptions allows the program to crash and you can get a core dump to help with debugging. While this may be useful in debug mode, as it can help the debugger point you to the exact line of code that raised the exception, I like to ship programs that don't crash, and I can show the user a message saying a bug report was submitted.
Function try-catch blocks are only useful in constructors, and even then, not very useful at all. It's best to just forget they exist.