Throwing "exception" and continuing to "return the normal value" contradict.
As you wrote, you can remember the problem has happened in a some member of SomeObject or some variable which is passed as a reference to the constructor.
To prevent the caller not handling the error, you can construct a "signalling member" in such a way that if the caller is not polling it, you will assert in destructor of SomeObject (or in destructor of the signalling member).
Possible example of signalling member:
template <typename Base>
class Signal
{
private:
Base _val;
bool _polled;
public:
operator Base() const {_polled=true;return _val;}
// even when we do not set the value, we force the user to poll - it makes testing easier
Signal():_polled(false) {}
// but once we set it, we mark he has to poll
Signal(Base val):_val(val),_polled(false) {}
// if he does not, we assert
~Signal(){assert(_polled);}
};
If you set the value and the caller will not "get" it, the destructor will assert. If the caller will get it but ignore anyway, then you are out of luck - but this is the same with exceptions: if the caller catches it and ignores it, you cannot do a thing about it. Here is how would you use it:
SomeObject Foo(int input, Signal<int> &errorCode)
{
SomeObject result;
// do something.
if (somethingBadHappened)
errorCode = 1234; //oh, we need to warn the caller.
return result;
}
void Main()
{
SomeObject object;
Signal<int> error;
object = Foo(1,error);
// error not served? => assert
// to prevent the assert firing, uncomment the following line
// int handle = error;
}
Note: instead of assert, you could also throw an exception in the Signal destructor. Be aware, though, that throwing from destructors is hard to get right - you need to be extra carefull about how exactly you use the Signal class (and what will be used as Base for it) then.