"The Parameter Is Incorrect" MFC exception - c++

This is native C++. No .NET framework involved.
I am trying to figure out which exception is thrown when the CListBox gets an invalid parameter. Turns out MFC uses this exception quite a lot but I can't determine the actual exception type thrown. I have tried a lot of different types on the catch (int, const char , std:) but the only one besides catch(...) that catches it is the (const void *). Looking the memory structure, I still don't have a clue what is actually thrown.
Does any one know what it is or how to determine what it thrown?
This is a sample MFC application. ListBox is a CListBox. The application is nothing more than the default DialogBox based MFC application that VS builds automatically. The only change is that I added a list box and the code you see below in the OK button handler.
void CMFCApplication1Dlg::OnBnClickedOk()
{
try
{
CString Value;
ListBox.GetText( -1, Value );
Value = "none";
}
catch ( CException & exception )
{
exception.Delete();
}
catch ( const void * e )
{
}
catch (...)
{
}
CDialogEx::OnOK();
}

To explain why you get the exception, it looks like when you use the CString version of CListBox::GetText() it will throw an E_INVALIDARG exception if the passed index is not valid. Tracing through the MFC code is a bit of work but CListBox::GetText() looks like:
void CListBox::GetText(int nIndex, CString& rString) const
{
ASSERT(::IsWindow(m_hWnd));
GetText(nIndex, rString.GetBufferSetLength(GetTextLen(nIndex)));
rString.ReleaseBuffer();
}
CListBox::GetTextLen(-1) will return LB_ERR which is -1. If you follow the code for CString::GetBufferSetLength() you eventually end up in CString::SetLength():
void SetLength(_In_ int nLength)
{
ATLASSERT( nLength >= 0 );
ATLASSERT( nLength <= GetData()->nAllocLength );
if( nLength < 0 || nLength > GetData()->nAllocLength)
AtlThrow(E_INVALIDARG);
GetData()->nDataLength = nLength;
m_pszData[nLength] = 0;
}
with nLength == -1 and thus the exception.

The answer is:
catch ( const COleException * e )
I was using catch ( const COleException & e ) as all the text books say one should. Oh well.
Details can be found at Exception Handling in MFC, and Exceptions: Catching and Deleting Exceptions in particular.

Note that this invalid argument exception can now happen through a call to UpdateAllViews(). I traced the code deep through the MFC libraries. It results from a macro that only generates the throw for release builds.
Since it is so deep, it can occur from several other functions.

Related

Error handling in C library used by C++ program

I am using a C library (which I also wrote) within a C++ program and I want to know how I should be doing error handling from within the C library such that the C++ program is able to decide how to handle errors that may happen.
I originally had the C library return a value indicating an error has occurred (e.g. NULL or -1) and just print an error message to stderr but this is not easily capturable by programs using the library.
Ideally I want the C++ program to be able to retrieve an error message string from the C library so that it can handle the error whichever way it wants to, such as logging the error message elsewhere.
Is there a common design idiom for this?
All methods, that require global state (errno, get_last_error, ...), will have concurrency issues. Using the return channel ruins return value optimization for you.
A common option is to take a pointer to an error struct as first or last parameter.
struct Error {
const char* message;
int code;
};
int my_nice_c_function( int a, int b, Error* err ) {
if ( err != NULL ) {
err->message = "";
err->code = 0;
}
return a + b;
}
When you pass them in from C++ it could look like:
Error err;
...
auto foo = my_nice_c_function( 5, 6, &err );
if ( err.code != 0 ) {
std::cerr << err.message << std::endl;
}
But make sure to always set the error members!

How to approach to reformat error messages without embedding string object in custom exception classes?

I have read answers to following questions ->
c++ exception : throwing std::string
c++ Exception Class Design
My requirement is to catch exceptions and allow a mechanism to reformat the error messages and then re-throw the exceptions.
So I thought of writing my exception class which will provide a method to reformat the error message at various catch points.To make reformatting easy, I'm embedding a string object in myexception_base class.
I have also referred to this article -> http://www.boost.org/community/error_handling.html which clearly says not to embed string objects in exception classes.
The article also has a quote "Peter Dimov makes an excellent argument that the proper use of a what() string is to serve as a key into a table of error message formatters." but it does not elaborate on it any further.
I have written the code as given below and my questions are -
1) If I don't embed a string object in my exception class, it will make it difficult to reformat the what messages. Please tell me How shall I approach to my requirement without embedding a string object in my exception class?
2) If I carry on with my current approach of embedding a string object and providing a method to format error message. Is my way of handling some scenarios correct ? (Issue 1 and Issue 2 in which error msg doesn't get formatted)
Issue 1 - wrong exception getting propagated to catch points ?
Issue 2 - Error Message not getting formatted in some scenarios ?
Issue 1 and Issue 2 are mentioned in comments in code below.
Kindly have a look at the code. I have given lot of comments in code so lines of code has increased but if I remove the comments it has very less lines of code.
#include <string>
#include <exception>
#include <iostream>
using namespace std;
class myexception_base : public exception {
private:
string error_msg;
public:
myexception_base(const char* str) : error_msg(str) {
// std::string here here can throw an exception while error_msg
//initialisation through MIL.
// myexception_base object will not be constructed
// and wrong exception will be propagated to catch point(Issue 1)
}
const char* what() const throw() {
try {
return error_msg.c_str();
} catch (...) {}
// c_str can throw.
// I can't remove throw specification from what()
// because what() in base std::exception has throw() specification
// In case c_str() throws an exception program will terminate
// So to stop abnormal termination of program c_str
// is wrapped in a try catch block to ignore std::string exception
// program will not terminate but what message is not reformatted
// in such scenario (Issue 2)
}
void append_error_msg(const char* str) {
error_msg.append(str);
// append can throw
// Again error_msg will not be formatted (Issue 2)
}
~myexception_base() throw() {
}
};
void f();
void f2();
void f() {
throw myexception_base("Error Msg1");
}
void f2() {
//Some intermediate Catch point will reformat e.what() msg
//by appending an error msg2
try {
f();
}
catch (myexception_base& e) {
e.append_error_msg(": Error Msg2");
throw;
}
}
int main () {
try {
f2();
}
catch(const exception& e) {
// Finally the exception is caught in the upper most layer
// and proper error_msg is given to user
cout<<e.what()<<"\n";
}
}
According to the boost documentation embedding classes which might throw during their lifetime are not an excellent candidate to be used in the exception handler mechanism, so I would like to suggest that you will simply use the good old C way of handling strings. It will require some extra effort to bring it up and running but with them you have eliminated one source of error.
So, basically there are two approaches:
In the myexception_base you declare the error_msg as being an array of N chars. In the append_error_msg you carefully check that the length of the NEW string (after the append) is not greater than N and if it is not, then you use strcat or one of the other C string handling methods. This approach might be good, since it does not allow memory leaks through the exception handling mechanism, however you can have only a limited length of error message.
In the myexception_base you declare the error_msg as being a char* (a char pointer). In the constructor you callocmemory for it (do not use new since new might throw) and in the append_error_message you realloc the pointer to be the new size (ie. old size + string to be appended.size + 1 for the 0) and then memcpy to the requested position (ie. at the position of the end of the old string in the newly allocated string). Of course, do not forget to check all the allocations/re-allocations that they have returned a valid value otherwise you might get funny behavior. And last, but not least, to avoid the classical memory leaks, free the memory of the char* in the destructor.
Good luck!

Angelscript class method registration

I am writing some basic code to experiment with Angelscript, however I cannot get even the simplest functions to work correctly. Here is the basic code block:
class Engine {
public:
void print(std::string&);
};
Engine::print(std::string &msg)
{
cout<<msg.c_str()<<endl;
}
Here is the actual code that initializes and registers C functions for Angelscript:
int r;
asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
r = engine->SetMessageCallback(asMETHOD(Engine,MessageCallback), this,asCALL_THISCALL);
assert( r >= 0 );
RegisterStdString(engine);
r = engine->RegisterObjectType("Engine", 0, asOBJ_APP_CLASS_CONSTRUCTOR);
cout<<"r was: "<<r<<endl;
assert( r >= 0 );
r = engine->RegisterObjectMethod("Engine","void print(const string &in)", asMETHOD(Engine,print), asCALL_THISCALL);
assert( r >= 0 );
At first I did not have the function "RegisterObjectType()" present, so running the program would throw a "'Engine' is not a valid type" error even though it was a valid class. So I found a function called "RegisterObjectType()" and implemented it as above and now it's throwing a "Invalid Flag" error on the 'RegisterObjectType()' function in the last field. I've tried all the class flags and it still throws this error.
What is the proper method for registering a class method into Angelscript? The documentation example didn't seem to work. It seems to snip out everything except the actual function it is explaining, for example, it did not hint about registering object types with the class method registration code. Or it was not very clear about it.
I should mention that all the errors encountered are runtime errors thrown by the angelscript libraries and not compiler errors.
Thanks!
The as_OBJ_APP_CLASS_CONSTRUCTOR is not proper flag, it should be used combined with other as_OBJ_APP... flags. Check this for example (bit outdated), and clarifications of ways to register object type: http://www.darawk.com/code/CoHClient/Angelscript/sdk/docs/articles/register_object.html.
Of course manual is your best friend:
http://www.angelcode.com/angelscript/sdk/docs/manual/index.html
(Using Angelscript->Registering the application interface->Registering an object type)

Turning GetLastError() into an exception

I have a Visual Studio 2008 C++ project that uses a Win32Exception class in cases where there is an exceptional error. The Win32Exception class looks like this:
/// defines an exception based on Win32 error codes. The what() function will
/// return a formatted string returned from FormatMessage()
class Win32Exception : public std::runtime_error
{
public:
Win32Exception() : std::runtime_error( ErrorMessage( &error_code_ ) )
{
};
virtual ~Win32Exception() { };
/// return the actual error code
DWORD ErrorCode() const throw() { return error_code_; };
private:
static std::string ErrorMessage( DWORD* error_code )
{
*error_code = ::GetLastError();
std::string error_messageA;
wchar_t* error_messageW = NULL;
DWORD len = ::FormatMessageW( FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
*error_code,
MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),
reinterpret_cast< LPWSTR >( &error_messageW ),
0,
NULL );
if( NULL != error_messageW )
{
// this may generate a C4244 warning. It is safe to ignore.
std::copy( error_messageW,
error_messageW + len,
std::back_inserter( error_messageA ) );
::LocalFree( error_messageW );
}
return error_messageA;
};
/// error code returned by GetLastError()
DWORD error_code_;
}; // class Win32Exception
The class works well in the situations it has been used in. What I would like to know is if there are any obvious cases where this will fail that I should be aware of. Any other gotchas, caveats, or general suggestions on improvements are welcome.
Please note that the boost library is not an option for this code.
This has already done by several people, including yours truly
https://github.com/BillyONeal/Instalog/blob/master/LogCommon/Win32Exception.hpp
https://github.com/BillyONeal/Instalog/blob/master/LogCommon/Win32Exception.cpp
Ironically, your code is not exception safe.
if( NULL != error_messageW )
{
// this may generate a C4244 warning. It is safe to ignore.
std::copy( error_messageW,
error_messageW + len,
std::back_inserter( error_messageA ) );
::LocalFree( error_messageW );
}
Note that if the back_inserter causes std::bad_alloc to be thrown, the memory allocated inside FormatMessage is leaked.
What a coincidence! I use a similar code in all my projects! It is actually a good idea.
This code is problematic:
// this may generate a C4244 warning. It is safe to ignore.
std::copy( error_messageW,
error_messageW + len,
std::back_inserter( error_messageA ) );
It just trancates WCHARs to chars. Your can either use FormatMessageA explicitly to get a message in the current code-page (ok, you can't as you said), or make convention that all your stings are UTF-8 encoded. I chose the later, see this why.
Error message by itself may be not useful. Capturing the stack trace may be a good idea.
Realize this is old, but at least with VC++ 2015 you can throw a system_error that will do all this with the system_category() function:
try
{
throw system_error(E_ACCESSDENIED, system_category(), "Failed to write file");
}
catch (exception& ex)
{
cout << ex.what();
}
This would print: "Failed to write file: Access is denied"
FormatMessage may itself fail. Some neutral "Unknown error with code %d" might be in order for such case.
Some error codes are not really errors (ERROR_ALREADY_EXISTS), depending on what user is expecting.
Some system functions return their own error codes (notable example being SHFileOperation) that you must handle separately. If you want them to be handled, that is.
Consider having additional information inside exception: where is exception being thrown from (source file and line), what system function caused exception, what were the parameters of the function (at least the identifying ones, like file name, handle value, or some such). Stack trace is also good.
What I would like to know is if there
are any obvious cases where this will
fail that I should be aware of. Any
other gotchas, caveats, or general
suggestions on improvements are
welcome.
The main I've problem I've had with such message retrieval has been ERROR_SUCCESS. It's rather perplexing when some operation fails, accompanied by error message "The operation succeeded". One wouldn't think that could happen, but it does.
I guess this is a special case of what Dialecticus noted, that "Some error codes are not really errors", but for most of those codes at least the message is generally acceptable.
The second problem is that most Windows system error message have a carriage return + linefeed at the end. It's problematic for insertion of messages into other text, and it breaks the convention for C++ exception messages. So, good idea to remove those chars.
Now, instead of repeating all that others have already noted, a few words about the design.
The ErrorMessage function would much more usable if was made public or moved out of the class, and took the error code by value, instead of taking pointer argument. This is the principle of keeping separate responsibilities separate. Promotes reuse.
The code in ErrorMessage would be more clear and safe and efficient if you used a destructor to deallocate the memory. Then you could also just construct the string directly in the return statement instead of using a copy loop with back inserter.
Cheers & hth.,
I was recently working on a very similar class and after reading this thread tried to make the copying part exception-safe. I introduced a little helper class that does nothing but hold the pointer to the string returned by ::FormatMessage and free it with ::LocalFree in its destructor. Copying, assigning and moving is not allowed, so one cannot get into trouble.
Here is what I came up with in total:
class windows_error {
public:
windows_error(wchar_t const* what);
// Getter functions
unsigned long errorCode() const { return _code; }
wchar_t const* description() const { return _what; }
std::wstring errorMessage() const { return _sys_err_msg; }
private:
unsigned long _code;
wchar_t const* _what;
std::wstring _sys_err_msg;
};
// This class outsources the problem of managing the string which
// was allocated with ::LocalAlloc by the ::FormatMessage function.
// This is necessary to make the constructor of windows_error exception-safe.
class LocalAllocHelper {
public:
LocalAllocHelper(wchar_t* string) : _string(string) { }
~LocalAllocHelper() {
::LocalFree(_string);
}
LocalAllocHelper(LocalAllocHelper const& other) = delete;
LocalAllocHelper(LocalAllocHelper && other) = delete;
LocalAllocHelper& operator=(LocalAllocHelper const& other) = delete;
LocalAllocHelper& operator=(LocalAllocHelper && other) = delete;
private:
wchar_t* _string;
};
windows_error::windows_error(wchar_t const* what)
: _code(::GetLastError()),
_what(what) {
// Create a temporary pointer to a wide string for the error message
LPWSTR _temp_msg = 0;
// Retrieve error message from error code and save the length
// of the buffer which is being returned. This is needed to
// implement the copy and assignment constructor.
DWORD _buffer_size = ::FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, _code, 0, _temp_msg, 0, NULL);
if(_buffer_size) {
// When calling _sys_err_msg.resize an exception could be thrown therefore
// the _temp_msg needs to be a managed resource.
LocalAllocHelper helper(_temp_msg);
_sys_err_msg.resize(_buffer_size + 1);
std::copy(_temp_msg, _temp_msg + _buffer_size, _sys_err_msg.begin());
}
else {
_sys_err_msg = std::wstring(L"Unknown error. (FormatMessage failed)");
}
}
Maybe this will be useful for some of you.

how to return multiple error codes from C++ function

What is a good way to return success or one or more error codes from a C++ function?
I have this member function called save(), which saves to each of the member variables, there are at least ten of these member variables that are saved-to, for the call to save(), I want to find out if the call failed, and if so, on which member variable (some are hard failures, some are soft).
You can either return an object that has multiple error fields or you can use 'out'parameters.
How you do this depends on your design and what exactly you are trying to return back. A common scenario is when you need to report back a status code along with a message of sorts. This is sometimes done where the function returns the status code as the return value and then returns the message status via an 'out' parameter.
If you are simply returning a set of 'codes', it might make more sense to construct a struct type and return that. In that case, I would be prone to pass it in as an out parameter and have the method internally update it instead of allocating a new one each time.
Are you planning on doing this once or many times?
I know this doesn't really answer your question, but...
In C++ you should use exceptions instead of returning error codes. Error codes are most commonly used by libraries which don't want to force the library user to use a particular error handling convention, but in C++, we already have stdexcept. Of course, there might be reasons you don't use exceptions, such as if you're writing embedded code or kernel extensions.
I usually use a boost::tuple:
typedef boost::tuple<int,int> return_value;
return_value r = my_function();
int first_value = boost::get<0>( r );
int second_valud = boost::get<1>( r );
EDIT
You can also use boost::tie to extract the values from a tuple:
boost::tie( first_value, second_value ) = r;
The simplest way to return two values is with the std::pair<> template:
I would use a bitset if you're intention is to purely return error states. e.g.
const bitset<10> a_not_set(1);
const bitset<10> b_not_set(2);
const bitset<10> c_not_set(4);
...
bitset<10> foo(T& a, T& b, T& c, ...)
{
bitset<10> error_code = 0;
...
if ( /* a can't be set */ )
{
error_code |= a_not_set;
}
...
if ( /* b can't be set */ )
{
error_code |= b_not_set;
}
...
// etc etc
return error_code;
}
bitset<10> err = foo(a, b, c, ... );
if (err && a_not_set)
{
// Blah.
}
You need to return them as output parameters:
bool function(int& error1, int& error2, stringx& errorText, int& error3);
You can use an integer with bit manipulation (aka flags).
I probably try to throw an exception first but it depends on your coding paradigm. Please check some books or articles about reasons why c++ exception handling might be better.
If I really need to stick to retrun-error-code style, I would define a eunm type for specifying errors with bit operations..
enum error
{
NO_ERROR = 0,
MEMBER_0_NOT_SAVED = 1,
MEMBER_1_NOT_SAVED = 1 << 1,
MEMBER_2_NOT_SAVED = 1 << 2,
// etc..
};
int save()
{
int ret = NO_ERROR;
// fail to save member_0
ret |= MEMBER_0_NOT_SAVED;
// fail to save member_1
ret |= MEMBER_1_NOT_SAVED;
// ....
return ret;
}
int main(void)
{
int ret = save();
if( ret == NO_ERROR)
{
// good.
}
else
{
if(ret & MEMBER_0_NOT_SAVED)
{
// do something
}
if(ret & MEMBER_1_NOT_SAVED)
{
// do something
}
// check the other errors...
}
}
This is just a rough example. It's better to put this into a class or use a namespace.
I am not familiar with the internals and constrains of your project, but if possible, try to use exceptions instead of error codes.
The reasons are listed here, at C++ FAQ lite, and they conclude with:
So compared to error reporting via return-codes and if, using try / catch / throw is likely to result in code that has fewer bugs, is less expensive to develop, and has faster time-to-market.