Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::future::get() does not catch the exception when the async function throws and program crashes

Tags:

c++

std

get

future

I am trying to call the future::get() function from the function started using the std::async function. In the async function I am throwing so that I can catch the exception in the future::get() call. However, I get an exception in the get() call that is not caught in the catch bloc and the program crashes with unhandeld exception. What am I missing ?

#include "stdafx.h"
#include <iostream>
#include <future>

void AsyncMethodThrowsExceptionTest();
void AsyncMethodThrowsException();

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    AsyncMethodThrowsExceptionTest();
    return 0;
}


void AsyncMethodThrowsExceptionTest()
{

    std::future<int> executionFuture;

    try
    {
        executionFuture = async(launch::async, AsyncMethodThrowsException);
    }
    catch(...)
    {
        cout << "caught ex [1]";
    }

    std::future_status::future_status status;

    status = executionFuture.wait_for(std::chrono::milliseconds(500u));
    if(status == std::future_status::deferred)
    {
        cout << "AsyncMethodThrowsException has not started";
    }
    else if(status == std::future_status::timeout)
    {
        cout << "AsyncMethodThrowsException timed out";
    }
    else if(status == std::future_status::ready)
    {
        cout << "AsyncMethodThrowsException successfully completed";
        try
        {
            if(executionFuture.valid())
            {
                executionFuture.get();
            }
        }
        catch(const std::future_error& ex)
        {
            cout << "AsyncMethodThrowsExceptionTest catch block";
        }
    }
}

void AsyncMethodThrowsException()
{
    throw(new exception("Exception from AsyncMethodThrowsException"));
}
like image 919
Rajib Ghosal Avatar asked Dec 29 '25 21:12

Rajib Ghosal


1 Answers

Not only are you throwing a pointer to a std::exception in AsyncMethodThrowsException (there's no reason to do this), you're both catching a reference to an exception not a pointer, and a reference to a child class of std::exception at that; std::future::get() throws the exact exception thrown in the called function, not a std::future_error.

There are a couple of other syntax issues:

  • std::future<int> executionFuture should be std::future<void> executionFuture
  • std::future_status::future_status status should be std::future_status status.
  • std::exception does not have a constructor that takes a char const* or a std::string, this might be a compiler extension.

To sum things up:

#include <iostream>
#include <future>

void AsyncMethodThrowsExceptionTest();
void AsyncMethodThrowsException();

using namespace std;

int main()
{
  AsyncMethodThrowsExceptionTest();
}


void AsyncMethodThrowsExceptionTest()
{
  std::future<void> executionFuture;

  try
  {
    executionFuture = async(launch::async, AsyncMethodThrowsException);
  }
  catch (...)
  {
    cout << "caught ex [1]";
  }

  std::future_status status = executionFuture.wait_for(std::chrono::milliseconds(500u));
  if (status == std::future_status::deferred)
  {
    cout << "AsyncMethodThrowsException has not started";
  }
  else if (status == std::future_status::timeout)
  {
    cout << "AsyncMethodThrowsException timed out";
  }
  else if (status == std::future_status::ready)
  {
    cout << "AsyncMethodThrowsException successfully completed";
    try
    {
      if(executionFuture.valid())
      {
        executionFuture.get();
      }
    }
    catch(const std::exception& ex)
    {
      cout << "AsyncMethodThrowsExceptionTest catch block";
    }
  }
}

void AsyncMethodThrowsException()
{
  throw runtime_error("Exception from AsyncMethodThrowsException");
}
like image 101
user657267 Avatar answered Jan 01 '26 11:01

user657267



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!