Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does this code catch block not execute?

The catch handler is not run. But why?

If the thread t is started before the try block, the catch handler runs.

If the catch block's type does not match the type thrown, the program exits explaining that the thread terminated with an uncaught exception, suggesting that the exception is handled, yet the catch block isn't run.

#include <iostream>
#include <thread>

using namespace std;

void do_work() {}

int main() {
  std::cerr << "RUNNING" << std::endl;
  try {
    thread t(do_work);
    std::cerr << "THROWING" << std::endl;
    throw logic_error("something went wrong");
  } catch (logic_error e) {
    std::cerr << "GOTCHA" << std::endl;
  }

  return 0;
}

Compile command:

c++ -std=c++14 -pthread -pedantic -Wall -Wextra -O0 scratch.cpp -o scratch
like image 719
sam Avatar asked Jun 16 '15 08:06

sam


People also ask

Does code execute after catch block?

Code after the try/catch block will not get executed unless the exception is caught by a catch block and not rethrown.

How do you execute catch block?

When a catch -block is used, the catch -block is executed when any exception is thrown from within the try -block. For example, when the exception occurs in the following code, control transfers to the catch -block.

What happens if try catch block is not used?

1 Answer. Explanation: If try catch block is not used the exception thrown by the program will be uncaught hence will result into error(s).

Why catch block is not a function?

The reason why your try catch block is failing is because an ajax request is asynchronous. The try catch block will execute before the Ajax call and send the request itself, but the error is thrown when the result is returned, AT A LATER POINT IN TIME. When the try catch block is executed, there is no error.


2 Answers

You forgot to join the thread :

try {
  thread t(do_work);
  t.join();                                    // <<< add this
  std::cerr << "THROWING" << std::endl;
  throw logic_error("something went wrong");
} catch (logic_error e) {
  std::cerr << "GOTCHA" << std::endl;
}

A joinable thread that goes out of scope, causes terminate to be called. So, you need to call either join or detach before it goes out of scope.

like image 124
Sander De Dycker Avatar answered Oct 20 '22 23:10

Sander De Dycker


In C++11, 30.3.1.3, thread destructor the standard says

If joinable() then terminate(), otherwise no effects. [Note: Either implicitly detaching or joining a joinable() thread in its destructor could result in difficult to debug correctness (for detach) or performance (for join) bugs encountered only when an exception is raised. Thus the programmer must ensure that the destructor is never executed while the thread is still joinable. —end note]

Thus your program terminates once the thread destructor is called because the scope ends and the catch logic is never executed.

If you want your program to catch the exception out of the thread's scope but throw while the thread is still joinable, you'll need to catch it in the scope of the thread itself, join or detach the thread and rethrow whatever has been catched.

try 
{
  std::thread t(foo);
  try
  {
    std::cerr << "THROWING" << std::endl;
    throw std::logic_error("something went wrong");
  }
  catch (...) // catch everything
  {
    t.join(); // join thread
    throw; // rethrow
  }
  t.join();
}
catch (std::logic_error & e) 
{
  std::cerr << "GOTCHA: " << e.what() << std::endl;
}
like image 45
Pixelchemist Avatar answered Oct 20 '22 23:10

Pixelchemist