   Writing helpful error messages
  Just a general question to the community, but can anyone show me how to catch certain errors and provide more helpful/descriptive messages in the output/error list tabs in Visual Studio C++.  Any help would be appreciated.   
  Any helpful tips and/or guidelines ( "do's and don'ts" ) would be helpful as well   ;  Certain errors such as? File Opening and things?A good way to would be to use the try-catch method of exception handling.   ;  Generally yes, or even information that would assist with template parameters or member access.  I figured it would be a try catch throw thing (though I'll try to restrict the code for such things to debug)   ;  Use return codes to ask if you should be worried about the state of your application, and use macros paired with __LINE__, etc. to trace where a problem occurred. this is one of the few occasions macros aren't so evil.If you need human readable strings, write a method that returns a string based on one of the return codes.  I once thought of writing specific error strings somewhere whenever an error occurred. All I can say about that is: Don't do that... It becomes a headache. [smile] Keep human readable strings describing errors separate from the rest of your code to reduce code noise.If you need a place to put error messages, runtime logs are reliable.   ;  I wrote a small class that gets thrown which contains some info like an error message, line number, file name, function etc.I also want few exception throwing at release build, so some error messages don't get included in release build (only critical ones, the rest is for what a debug build is meant to do).exception.hpp/* DaevsLib::DaevsCommon * * Copyright (c) 2010 Taco de Wolff * * * Taco de Wolff a.k.a Daevius * * Visit: http://www.daevslib.com * * License: (BSD) * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in *    the documentation and/or other materials provided with the *    distribution. * 3. Neither the name of this library nor the names of its contributors *    may be used to endorse or promote products derived from this *    software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */#ifndef DAEVSCOMMON_EXCEPTION#define DAEVSCOMMON_EXCEPTION#ifdef _MSC_VER #if _MSC_VER <= 1200  #define __FUNCTION__ "?" #endif#endif#if defined(DEBUG) && defined(DEBUG_VERBOSE)    #define GLOBAL_LOG(message) { std::cerr << '\"' << message << "\"\n"; }    #define LOG(message) { std::cerr << '\"' << message << "\" from " << __FILE__ << '(' << __LINE__ << ")::" << __FUNCTION__ << '\n'; }#else    #define GLOBAL_LOG(message) { }    #define LOG(message) { }#endif#ifdef DEBUG    #define GLOBAL_WARNING(message) { std::stringstream stream; stream << message; throw DaevsCommon::Exception(stream.str().c_str(), DaevsCommon::ExceptionType::Warning, DaevsCommon::ExceptionLocality::Global); }    #define WARNING(message) { std::stringstream stream; stream << message; throw DaevsCommon::Exception(stream.str().c_str(), DaevsCommon::ExceptionType::Warning, DaevsCommon::ExceptionLocality::Local, __FILE__, __FUNCTION__, __LINE__); }#else    #define GLOBAL_WARNING(message) { }    #define WARNING(message) { }#endif#define GLOBAL_ERROR(message) { std::stringstream stream; stream << message; throw DaevsCommon::Exception(stream.str().c_str(), DaevsCommon::ExceptionType::Error, DaevsCommon::ExceptionLocality::Global); }#define ERROR(message) { std::stringstream stream; stream << message; throw DaevsCommon::Exception(stream.str().c_str(), DaevsCommon::ExceptionType::Error, DaevsCommon::ExceptionLocality::Local, __FILE__, __FUNCTION__, __LINE__); }#include <iostream>#include <sstream>#include <string>#include <daevscommon/api.hpp>namespace DaevsCommon{    ////////////////////////////////////////////////////////////////    namespace ExceptionType    {   enum DAEVSCOMMON_API Enum   {  Warning,  Error   };    }    namespace ExceptionLocality    {   enum DAEVSCOMMON_API Enum   {  Local,  Global   };    }    ////////////////////////////////////////////////////////////////    class DAEVSCOMMON_API Exception    {    public:   Exception(const char *i_message = "", ExceptionType::Enum i_type = ExceptionType::Error, ExceptionLocality::Enum i_locality = ExceptionLocality::Global, const char *i_file = NULL, const char *i_function = NULL, unsigned int i_line = 0);   ////////////////   const char *what() const;   const char *message() const;   ExceptionType::Enum type() const;   const char *type_text() const;   ExceptionLocality::Enum locality() const;   const char *file() const;   const char *function() const;   unsigned int line() const;    private:   const char *m_message;   ExceptionType::Enum m_type;   ExceptionLocality::Enum m_locality;   const char *m_file;   const char *m_function;   unsigned int m_line;    };    ////////////////////////////////////////////////////////////////}#endif // DAEVSCOMMON_EXCEPTIONexception.cpp#include <daevscommon/exception.hpp>namespace DaevsCommon{    ////////////////////////////////////////////////////////////////    Exception::Exception(const char *i_message, ExceptionType::Enum i_type, ExceptionLocality::Enum i_locality, const char *i_file, const char *i_function, unsigned int i_line) :   m_message(i_message),   m_type(i_type),   m_locality(i_locality),   m_file(i_file),   m_function(i_function),   m_line(i_line)    {    }    ////////////////////////////////////////////////////////////////    const char *Exception::what() const    {   if (m_locality == ExceptionLocality::Local)   {  std::stringstream stream;  stream << '\"' << m_message << "\" (" << type_text() << ") from " << m_file << '(' << m_line << ")::" << m_function << '\n';  return stream.str().c_str();   }   else   {  std::stringstream stream;  stream << '\"' << m_message << "\" (" << type_text() << ")\n";  return stream.str().c_str();   }    }    const char *Exception::message() const    {   return m_message;    }    ExceptionType::Enum Exception::type() const    {   return m_type;    }    const char *Exception::type_text() const    {   if (m_type == ExceptionType::Warning)   {  return "warning";   }   else   {  return "error";   }    }    ExceptionLocality::Enum Exception::locality() const    {   return m_locality;    }    const char *Exception::file() const    {   return m_file;    }    const char *Exception::function() const    {   return m_function;    }    unsigned int Exception::line() const    {   return m_line;    }    ////////////////////////////////////////////////////////////////}Maybe you find it useful...it works well for me, though this code hasn't been reviewed by others (yet).Sample usage:void f(){    LOG("shows up only in (verbose) debug mode");    WARNING("shows up in debug mode, not release");    GLOBAL_ERROR("critical error, global -> location is irrelevant, some number: " << 5 );}Hope this gives you some inspiration :)   ;  Besides exceptions, a lightweight error object is quite helpful.  The one we use at work is a wrapper for two integers, an OS error and a user-defined error.  This allows you to have application-specific errors that can be backed by an OS error, if you need it.  A separate table allows us to convert the error object into a string representation based on the error codes, and the type has other convenience features like implicit bool conversion so you only have to dig into it when something goes wrong.   