How can I handle exception in catch block in c++ [duplicate] - c++

This question already has answers here:
Nested try...catch inside C++ exception handler?
(2 answers)
Closed 1 year ago.
say I have code
try
{
....
}
catch()
{
.... // exception occur here ... how to handled.
}
Is there any mechanism in c++ by which the above scenario can be handled.

If you think this is what you really want, you can do it like this:
try
{
try
{
//...
}
catch( ... )
{
//...
if( .. )
throw std::runtime_exception( "error occured" );
}
}
catch( std::runtime_exception& e )
{
// handle exception of exception handler
}

Related

Correctly catching the CDatabase::Close exception

I thought I would do a little digging about cataching exceptions.
According to this question (C++ catching all exceptions) one of the answers states:
[catch(...)] will catch all C++ exceptions, but it should be considered bad design.
At the moment I have used this approach:
CPTSDatabase::~CPTSDatabase()
{
try
{
CloseDatabase();
}
catch(...)
{
}
}
void CPTSDatabase::CloseDatabase()
{
if (m_dbDatabase.IsOpen())
m_dbDatabase.Close();
}
I thought that this was the correct way because when I trace into CDatabase::Close() it does something similar:
// Disconnect connection
void CDatabase::Close()
{
ASSERT_VALID(this);
// Close any open recordsets
AfxLockGlobals(CRIT_ODBC);
TRY
{
while (!m_listRecordsets.IsEmpty())
{
CRecordset* pSet = (CRecordset*)m_listRecordsets.GetHead();
pSet->Close(); // will implicitly remove from list
pSet->m_pDatabase = NULL;
}
}
CATCH_ALL(e)
{
AfxUnlockGlobals(CRIT_ODBC);
THROW_LAST();
}
END_CATCH_ALL
AfxUnlockGlobals(CRIT_ODBC);
if (m_hdbc != SQL_NULL_HDBC)
{
RETCODE nRetCode;
AFX_SQL_SYNC(::SQLDisconnect(m_hdbc));
AFX_SQL_SYNC(::SQLFreeConnect(m_hdbc));
m_hdbc = SQL_NULL_HDBC;
_AFX_DB_STATE* pDbState = _afxDbState;
AfxLockGlobals(CRIT_ODBC);
ASSERT(pDbState->m_nAllocatedConnections != 0);
pDbState->m_nAllocatedConnections--;
AfxUnlockGlobals(CRIT_ODBC);
}
}
And the CDatabase::Close documentation does not even state anything about exceptions being thrown.
The linked answer does state:
You can use c++11's new current_exception mechanism.
It is not clear if we can use this approach given the CDatabase class we are using.
Since CDatabase::Close() is using THROW_LAST to throw CDBException, you have to use catch (CDBException* e). Even if you are not handling it, you still have to Delete the error. You might as well do this when CDatabase methods are called directly:
void CPTSDatabase::CloseDatabase()
{
try
{
if (m_dbDatabase.IsOpen())
m_dbDatabase.Close();
}
catch (CDBException* e)
{
//TRACE(L"DB error: " + e->m_strError);
e->Delete();
}
}
Or use
CPTSDatabase::~CPTSDatabase()
{
try { CloseDatabase(); }
catch (CDBException* e) { e->Delete(); }
catch(...) {}
}
Because in this code it's not clear where the exceptions are coming from. catch(...) {} will deal with other exceptions. In general catch(...) {} is not recommended because it doesn't give useful information, it just says "something went wrong..."
Use Standard Library exceptions only if you are adding throw in your own code, or when using std functions. Example:
try { std::stoi("wrong argument"); }
catch (const std::exception& e) { TRACE("%s\n", e.what()); }
try { throw 123; }
catch (int i) { TRACE("%d\n", i); }

C++ - Avoiding multiple if statements for managing errors [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
Simple question.
I have this code in front of me:
if ( somethings() == false ) {
log("error when ...somethings()");
return false;
}
// do somethings
if ( somethings2() == false ) {
log("error when ...somethings2()");
return false;
}
// ...
// eventually
if ( somethingsN() == false ) {
log("error when ...somethingsN()");
delete myData;
return false;
}
Not sexy, right ? What would be the best method(/pattern ?) for improving this code ?
Solution 1:
I was wondering about using exceptions
try {
if ( somethings() == false )
throw std::runtime_error("error when ...somethings()");
// do somethings
if ( somethings2() == false )
throw std::runtime_error("error when ...somethings2()");
// ...
if ( somethingsN() == false )
throw std::runtime_error("error when ...somethingsN()");
}
catch ( std::exception& e ) {
log(e.what());
delete myData;
return false;
}
Solution 2:
Using nested if statements
if ( somethings() ) {
// do somethings...
if ( somethings1() ) {
// ... (eventually too many indent)
if ( somethingsN() ) {
return true;
}
}
}
delete myData;
return false;
What are your methods ?
I just want to improve my coding style here.
Note (edit)
"Do not use 'delete', use smart pointers instead such as unique_ptr" (thanks all)
Throw an exception on error rather than returning a magic value for the caller to check; avoid dynamic allocation except when you really need it; use smart pointers or other RAII types to manage it when you really do. Then the code becomes rather more straightforward:
somethings();
somethings2();
// ...
somethingsN();
#define CHECK(x) \
do { if (!(x)) throw MyException(#x, __FILE__, __LINE__); } while(0)
try {
// call third-party or
// C functions that don't throw
CHECK(thisone());
CHECK(thatone());
CHECK(theotherone());
// call my own functions
anotherone(); // throws
yetanotherone(); // throws
} catch (std::exception& e) {
log(e.what());
}
And of course no delete. unique_ptr is your friend.

Throwing from before a try...catch

If I have something like this:
if(condition1)
{
cout<<"ERROR: Expected an identifier \n.";
throw std::invalid_argument("");
}
if(condition2)
{
moveToken();
cout<<"ERROR: Expected a ' ( ' after Identifier \n.";
throw std::invalid_argument("");
}
moveToken();
try
{
try
{
newPosition = position;
fcNode->addChild(actual_params());
}
catch(exception &e)
{
position=newPosition;
if(condition3)
{
moveToken();
cout<<"ERROR: Expected a ' ) ' \n.";
throw std::invalid_argument("");
}
moveToken();
return fcNode;
}
if(condition4)
{
moveToken();
cout<<"ERROR: Expected a ' ) ' \n.";
throw std::invalid_argument("");
}
}
catch (exception &e)
{
moveToken();
throw std::invalid_argument("");
}
Would the exception thrown from the condition1 block be caught by any catch block or do I need to put the whole code in another try block and do a catch for it? (do throws get caught by first encountered catch blocks?) Thanks
If you have the following code:
try{
// block 1
}catch(exception){
// block 2
}
Every exception ONLY from block 1 will be caught and processed by block 2; catch block cannot catch any exception outside of block 1, so yes, you have to make one more try-catch
The execption will be caught by a type-matching catch block attached to whatever try block is enclosing the throw. If no try block is enclosing the throw in the current scope, or none of the attached catch blocks match the exception's type, then the exception will be sent up the call chain (i.e. to whatever function called this one). Repeat until we reach main, where the program will be terminated if the exception is not caught.
In the code you highlighted, there is no enclosing try block around that throw, so the exception will be handled further up the call chain, if at all.
Yes, you will have to put your hole code into a catch block since exception are only catch insde de surrounding try.
try {
//(.inside here can be catched.)
} catch(const std::exception& ex){
// here goes you catched exception
}
In C++, any type can be used for catching exceptions unlike in JAVA.
Ex:
try {
int integer_ = 11;
throw integer_;
} catch(int e) {
std::cout<<e<<"\n";//Displays 11
}
You can use a multi catch block like:
try {
int integer_ = 11;
std::string string_ = "thrown exception";
throw string_;
} catch(const std::string& e) {
std::cout<<e<<"\n";//Displays thrown exception
} catch(int e) {//This block is not treated, beacause no integer is thrown as an exception
std::cout<<e<<"\n";
}

C++: check if a certain exception type was thrown without external libraries

I am writing up some tests for a C++ program and I would like to check that my program throws certain types of exceptions when given certain inputs. I have seen that this is doable using external libraries such as googletest, but I would like to know how this was implemented.
I would like to separate the test data from the test code as much as possible. In particular, I would like something like this:
void RunTests(InputList inputs) {
for (int i = 0; i < inputs.length; i++) {
if (FunctionIAmTesting(inputs[i].value) has the expected exception behavior) {
// Pass
} else {
// Fail
}
}
}
InputList inputs = InputList({
Input(5), // no exception when 5 is an input
Input<MyExceptionClass>(0), // MyExceptionClass thrown when 0 is an input
Input<MyOtherExceptionClass>(-1) // MyOtherExceptionClass thrown when -1 is an input
});
RunTests(inputs);
If you know what the type of exception you are looking for then you can target an exception of that type in the catch () statement.
try {
// Test code.
// Unexpected success
std::cerr << "Expected a RelevantException to be thrown." << std::endl;
}
catch (RelevantException& e)
{
// Expected exception, continue.
}
catch (...) // Catch all
{
// Unexpected exception
std::cerr << "Unexpected exception encountered, expected "
"RelevantException." << std::endl;
}
A several years back I wrote some simple library for "mocking" objects. And my goal was to check everything related to function calls. In the tests I wrote something like that:
MyMockedObject my;
mock::expect(my, "foo").in(10).out(20).returns(30);
mock::expect(my, "bar").throws(logic_error("bar failed"));
int v;
// test that my::baz() invokes my.foo(10, v)
// then my.bar which fails with the exception
my.baz();
Your task seems to be a little bit easier. All that you need is a way how to describe your expectations and some hack in the test runner to verify them at the end of a test (accordingly to the input). Your expectations are exceptions, just construct them somehow and associate with the input. In your example you did a half part of your work.
typedef std::map<Input, Exception> Expectations;
typedef std::pair<Input, Exception> Expectation;
// somewhere before the tests
expectations.insert(make_pair(Input(5)), NoThrowAnything);
expectations.insert(make_pair(Input(0)), MyException("some message"));
expectations.insert(make_pair(Input(-1)), MyOtherException("another message"));
void run_test(const Expectation& expect)
{
try {
// run the real test here based on Input (expect.first)
check_expectation(expect);
} catch (const Exception& ex) {
check_expectation(expect, ex);
}
}
void run_all_tests(const Expectations& expects)
{
for (e : expects) {
try {
run_test(e);
} catch (const ExpectationException ex) {
// failed expectation
}
}
}
void check_expectation(const Expectation& expect)
{
if (expect.second != NoThrowAnything) {
throw ExpectationFailure(expect);
}
}
void check_expectation(const Expectation& expect, const Exception& ex)
{
if (expect.second != ex) {
throw ExpectationMismatch(expect, ex);
}
}

what's the benefit of the code [duplicate]

This question already has answers here:
In ArrayBlockingQueue, why copy final member field into local final variable?
(2 answers)
Closed 9 years ago.
While reading the source code of ArrayBlockingQueue, I found below code:
public E take() throws InterruptedException {
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
try {
while (count == 0)
notEmpty.await();
} catch (InterruptedException ie) {
notEmpty.signal(); // propagate to non-interrupted thread
throw ie;
}
E x = extract();
return x;
} finally {
lock.unlock();
}
}
why not use the code
public E take() throws InterruptedException {
lock.lockInterruptibly();
try {
try {
while (count == 0)
notEmpty.await();
} catch (InterruptedException ie) {
notEmpty.signal(); // propagate to non-interrupted thread
throw ie;
}
E x = extract();
return x;
} finally {
lock.unlock();
}
}
what's the Benefit of the line code :final ReentrantLock lock = this.lock;
This idea was popularized by Doug Lea - I think that the original idea was that the JVM could possibly perform some performance related optimization when there was a final local variable used.
Check out this thread from the OpenJDK thread which discusses this very question
Edit:
A little research threw up these two related questions on stack:
In ArrayBlockingQueue, why copy final member field into local final variable?
Java Lock variable assignment before use. Why?