1

I have a Foo class as follows

Foo.h

#pragma once
class Foo
{
public:
    Foo() = default;
    ~Foo() = default;

    void DoSomething();
};

Foo.cpp

#include "Foo.h"

void Foo::DoSomething()
{
    throw "something happened";
}

And I use the class like:

#include <iostream>
#include "Foo.h"

int main()
{
    try
    {
        Foo foo;
        foo.DoSomething();
    }
    catch (std::exception& e)
    {
        std::cout << e.what() << std::endl;
    }
}

I expect the code to go in the catch block. However, it never goes in there. What am I doing wrong here?

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
whoami
  • 1,689
  • 3
  • 22
  • 45
  • 7
    `"something happened"` is a `const char *`, not a `std::exception`. –  Oct 31 '18 at 19:33
  • Thanks, Is there any concept of global exception handler that can catch any types of unhanded exceptions? Coming from a java background and new to c++ – whoami Oct 31 '18 at 19:38
  • 1
    @BKS Not in C++. The closest we have is `catch (...)` which will catch anything but you can't actually access whatever was thrown so you could only have a generic message like `something bad happened` – NathanOliver Oct 31 '18 at 19:40
  • 1
    Yes - `catch(...)` –  Oct 31 '18 at 19:40
  • @Nathan To be pedantic, you can get at the type by re-throwing and re-catching. –  Oct 31 '18 at 19:42
  • 2
    afaik in java your throw exceptions all over the place when "something happened". In c++ excpetions aren't really cheap and are for cases when "something exceptional happened" – 463035818_is_not_an_ai Oct 31 '18 at 19:43
  • @NeilButterworth In `catch(...)` how would you rethrow the caught exception? – NathanOliver Oct 31 '18 at 19:44
  • 1
    @Nathan `throw;` –  Oct 31 '18 at 19:44
  • 1
    @NeilButterworth Awesome. Learned something new today \o/ – NathanOliver Oct 31 '18 at 19:46
  • @NathanOliver [this](https://stackoverflow.com/a/315967/4117728) mentions some current_exception in c++11 that i never heard of before to get a handle on the exception in a `catch(...)` – 463035818_is_not_an_ai Oct 31 '18 at 19:48
  • @NathanOliver [Lippincott Function](http://cppsecrets.blogspot.com/2013/12/using-lippincott-function-for.html?m=1) – Jesper Juhl Oct 31 '18 at 19:48
  • 1
    Any idea why question was down voted? Its very helpful to leave some suggestions so that people can learn and improve their questions. – whoami Oct 31 '18 at 20:41
  • 2
    @user463035818: They are cheaper than writing explicit error handling logic to unwind the stack manually (both in cost and maintainability). Throw exceptions when there is an error that can not be fixed locally. – Martin York Oct 31 '18 at 20:55
  • @MartinYork not sure what to say other than: You are right and my comment was silly :) – 463035818_is_not_an_ai Nov 01 '18 at 10:36

1 Answers1

10

When you do

throw "something happened"

You aren't throwing a std::exception. You are throwing a string literal which has a type of const char[N]. To catch it you would need a catch block like

catch (const char* e)
{
    std::cout << e << std::endl;
}

Alternatively you could throw something that derives from std::exception like a std::runtime_error and that would look like

void Foo::DoSomething()
{
    throw std::runtime_error("something happened");
}

...

catch (const std::exception& e) // catch by reference to const
{
    std::cout << e.what() << std::endl;
}

You can also specify a default handler like

catch (...)
{
    std::cout << "something bad happened - cannot recover" << std::endl;
}

which will catch any thrown exception but you wont be able to access whatever was thrown so you can only give a general message.

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
  • 1
    or catch anything with `catch (...)` – 463035818_is_not_an_ai Oct 31 '18 at 19:39
  • @user463035818 Just added that after seeing the comment from the OP – NathanOliver Oct 31 '18 at 19:43
  • Regarding `catch (...)`. You can use a Lippincott Function to rethrow the exception and catch specific ones to provide more detail (when possible). I have a `log_exception` function for just that. It is used in `try (...)` blocks and tries to catch my application specific exceptions and log those if it can, otherwise it catches `std::exception` and logs what it can. Finally it just gives up and does a `throw;` to rethrow the exception for anyone to handle better than just logging. – Jesper Juhl Oct 31 '18 at 20:05