I'm using the Xerces C++ DOM parser to read some XML files in a Visual C++ project. I have a class with a parse() method that is supposed to read and validate my XML source file. This is what the method looks like:
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/framework/LocalFileInputSource.hpp>
using namespace std;
XERCES_CPP_NAMESPACE_USE
unsigned long RulesParser::parse( const wstring &xmlFile )
{
if( parserInitialized_ == false ) {
try {
XMLPlatformUtils::Initialize(); /* initialize xerces */
} catch( XMLException const &e ) {
return Status::PARSER_INIT_FAIL;
}
}
parserInitialized_ = true; /* indicate xerces has been
successfully initialized */
if( pDOMParser_ != NULL ) {
delete pDOMParser_;
}
pDOMParser_ = new XercesDOMParser; /* create a DOM parser instance */
/* set xerces options */
pDOMParser_->setDoNamespaces( true ); /* enable namespace processing */
pDOMParser_->setDoSchema( true ); /* enable schema processing */
pDOMParser_->setValidationScheme( XercesDOMParser::Val_Always ); /* parser always validates */
pDOMParser_->setValidationSchemaFullChecking( true ); /* enable full schema checking */
auto_ptr< LocalFileInputSource > srcFile; /* XML source file loader */
try {
srcFile.reset( new LocalFileInputSource( xmlFile.c_str() ) );
} catch( const XMLException &e ) {
return Status::XML_SOURCE_LOAD_ERROR;
}
/* parse the file */
try {
pDOMParser_->parse( *srcFile );
} catch( const XMLException &e ) {
return Status::XML_SOURCE_PARSE_ERROR;
} catch( const DOMException &e ) {
return Status::XML_SOURCE_PARSE_DOM_ERROR;
}
return Status::OK;
}
The documentation for LocalFileInputSource says the constructor will throw an XMLException if the path doesn't resolve to a file. However, I can call this method with any arbitrary string and it executes to the end without any exceptions being raised. What am I doing wrong?
Also, the documentation for XercesDOMParser::parse() says a SAXException is one of the types of exceptions that it can throw. I find this confusing because from what I understand DOM and SAX parsers are 2 different animals, so why would the DOM parser throw a SAX exception?
See ErrorHandler documentation.
You must declare and define a class that inherits from ErrorHandler and implements its virtual methods (or you can extend the HandlerBase class).
Then you must call setErrorHandler on your parser instance passing an instance of your error handler, i.e. pDOMParser_->setErrorHandler(your_handler_instance).
Example usage from Xerces-C++ trunk samples: rows 231-233 of SAXPrint.cpp.
Update: example of custom error handler below.
#include <iostream>
#include <xercesc/sax/HandlerBase.hpp>
XERCES_CPP_NAMESPACE_USE
class CustomErrorHandler : public HandlerBase
{
public:
CustomErrorHandler() {}
void error(const SAXParseException& e)
{
handler(e);
}
void fatalError(const SAXParseException& e)
{
handler(e);
}
void warning(const SAXParseException& e)
{
handler(e);
}
private:
void handler(const SAXParseException& e)
{
char* message = XMLString::transcode(e.getMessage());
cerr << "line " << e.getLineNumber()
<< ", column " << e.getColumnNumber()
<< " -> " << message << "\n\n";
XMLString::release(&message);
}
};
I don't think that the documentation says what you think it does, it says it will; throw:
XMLException If the path is relative
and doesn't properly resolve to a
file.
Your task, should you choose to accept it, is to find out what "relative" means. I'm afraid I I haven't used Xerces for years (though it is quite competent) - I prefer to use small, simple SAX parsers to build my own models rather than use a DOM, and can't remember how the filename stuff works.
And I think that the reason that you might get SAX exceptions is that Xerces uses SAX to build its DOM.
The 2.8 Doc (you have linked) says,
XMLException If the path is relative and doesn't properly resolve to a file
are you actually using a relative path?
maybe this used to be the case for some platform specific cases, but I can't see where this is raised in Xercese 2.7 (code I happen to have).
Looking at LocalFileFormatTarget it can throw an exception for 'CouldNotOpenFile', but it isn't documented as raising an exception.
What version of xerces are you using?
Opening the file for reading/parsing looks like it might raise an exception for the missing file of type 'CouldNotReadFromFile'. But that could be caught up with the error handling as Vanni is talking about.
I know this is old, but yes indeed I found that XercesDOMParser throws a SAXParseException if the file is not found. No custom error handler needed, just catch that exception.
Related
Consider a class foo which has one or more functions which can report failure either through a logger or by throwing an exception if no logger was provided:
struct logger
{
// ...
};
struct foo
{
void set_logger(std::shared_ptr<logger> logger) { m_logger = std::move(logger); }
bool bar(const std::filesystem::path& path)
{
// Check path validity
if (not std::filesystem::exists(path) {
if (m_logger) {
m_logger->warn("path does not exist.");
return false;
}
else {
throw std::runtime_error("path does not exists.");
}
}
// Some random operation
try {
// Do something here that might throw
}
catch (const std::exception& e) {
if (m_logger) {
m_logger->warn("operation bar failed.");
return false;
}
else {
throw e;
}
}
return true;
}
private:
std::shared_ptr<logger> m_logger;
};
This does not only look ugly but is extremely error prone and as more functions are added to foo code will be repeditive.
Is there any kind of pattern or paradigm to abstract this logic away? Some kind of wrapper template I can construct to use inside foo's various functions when error reporting is needed?
Anything up to C++20 would be acceptable.
Is there any kind of pattern or paradigm to abstract this logic away? Some kind of wrapper template I can construct to use inside foo's various functions when error reporting is needed?
One thing you could do is to simply remove all the else { throw... } code and provide a default logger that throws an exception containing the logged message. If the client provides a different logger, fine, your code will use that; if not, it uses the default one. This scheme eliminates about half your error handling code and simplifies the flow while providing the same behavior, which seems like a positive outcome.
It's important to remember that logging a message is different from throwing an exception: it's often useful to be able to log a message that doesn't stop the flow of the program. So be sure to give your logger class methods that log without throwing as well; you might use a different log level for messages that are equivalent to exceptions.
Since your error case handling seems to follow the same structure, you could add a simple function that will do just that:
bool log_or_throw(logger * logger_, std::string const& message, std::exception const& exception) {
if (logger_) {
logger_->warn(message);
return false;
}
else {
throw exception;
}
}
And then you can change your error handling to a single line, probably making the flow a lot more readable:
if (not std::filesystem::exists(path) {
return log_or_throw(m_logger, "path does not exist.", std::runtime_error("path does not exists."));
}
I am new to protobuf (C++) and my code fails during parse of my messages. How can I get more details about the errors that occurred?
Example
The following snippet illustrates the problem:
const bool ok=my_message.ParseFromCodedStream(&stream);
if(ok){
std::cout<< "message parsed. evidence:\n"<< my_message.DebugString();
}
else{
std::cerr<< "error parsing protobuf\n";
//HOW CAN I GET A REASON FOR THE FAILURE HERE?
}
If you look inside protobuf code, you will find it's using its own logging system - based on macros. By default all these messages goes to stderr, but you can capture them in your program with SetLogHandler():
typedef void LogHandler(LogLevel level, const char* filename, int line,
const std::string& message);
The possible solution is to make your own errno-like mechanism (sorry for C++11-ishness):
typedef LogMessage std::tuple<LogLevel, std::string, int, std::string>; // C++11
typedef LogStack std::list<LogMessage>;
namespace {
LogStack stack;
bool my_errno;
} // namespace
void MyLogHandler(LogLevel level, const char* filename, int line,
const std::string& message) {
stack.push_back({level, filename, line, message}); // C++11.
my_errno = true;
}
protobuf::SetLogHandler(MyLogHandler);
bool GetError(LogStack* my_stack) {
if (my_errno && my_stack) {
// Dump collected logs.
my_stack->assign(stack.begin(), stack.end());
}
stack.clear();
bool old_errno = my_errno;
my_errno = false;
return old_errno;
}
And use it in your code:
...
else {
std::cerr<< "error parsing protobuf" << std::endl;
LogStack my_stack;
if (GetError(&my_stack) {
// Handle your errors here.
}
}
The main drawback of my sample code - it doesn't work well with multiple threads. But that can be fixed on your own.
Sometimes error information will be printed to the console, but that's it. There's no way to get extra error info through the API.
That said, there are only two kinds of errors anyway:
A required field was missing. (Information should be printed to the console in this case.)
The data is corrupt. It was not generated by a valid protobuf implementation at all -- it's not even a different type of protobuf, it's simply not a protobuf.
If you are seeing the latter case, you need to compare your data on the sending and receiving side and figure out why it's different. Remember that the data you feed to the protobuf parser not only must be the same bytes, but it must end at the same place -- the protobuf parser does not know where the message ends except by receiving EOF. This means that if you are writing multiple messages to a stream, you need to write the size before the data, and make sure to read only that many bytes on the receiving end before passing on to the protobuf parser.
I'm working on a small C++11 application (an SDL2 game) and i'm having a hard time "porting" some of my object-oriented knowledge from PHP/Java to C++. For example, in order to create an elegant error logging approach, i would create a class with various adapters and centralize logging there. I already did that in C++, but i have no idea on how my classes should be using the Logger class.
In Java and PHP, i would use dependency injection, and put the Logger as a class member variable in them. But in C++, what's the proper way? I don't really think that going static would be nice.
Oh man.
To me logging is similar to date/time handling: the basic case is trivial, but anything more than trivial is extremely complicated: no middle ground.
Let me advise you to look into a general purpose logging library such as Pantheios or Boost.Log.
The reason why I advice for this approach as opposed to making "your own effort", is that I know first hand how the "logging situation" goes:
you start with a simple "write to file" or "write to screen"
then you need to also log to another device
then you want to filter out severity levels
then you want to send your logs via pipes
then you want to turn off logging
And it all becomes very, very difficult, and the logging classes start polluting your code.
So, like I said: based on my limited experience, I would encourage you to look into the suggested libraries.
Good luck.
Edit: Boost.Log examples
Just for completeness of the post (refer to page for details).
Trivial case:
#include <boost/log/trivial.hpp>
int main(int, char*[]) {
BOOST_LOG_TRIVIAL(trace) << "A trace severity message";
BOOST_LOG_TRIVIAL(debug) << "A debug severity message";
BOOST_LOG_TRIVIAL(info) << "An informational severity message";
BOOST_LOG_TRIVIAL(warning) << "A warning severity message";
BOOST_LOG_TRIVIAL(error) << "An error severity message";
BOOST_LOG_TRIVIAL(fatal) << "A fatal severity message";
return 0;
}
One approach would be to pass a reference to a logger object around function calls. However, logging is a sort of an orthogonal aspect to application logic, so that explicitly passing that logger and having it as a member quickly becomes a nuisance and only adds artificial complexity.
I prefer having one global logger in the application. Modules can create its own loggers as child loggers of the main logger forming a hierarchy (I think this is similar to Python logging module) and control its output sink and verbosity independently if necessary.
I always use something like this:
class Log
{
public:
Log()
: m_filename( "dafault.log" )
{}
// if you wanna give other names eventually...
Log( const std::string & p_filename )
: m_filename( p_filename )
{}
virtual ~Log()
{
// implement your writeToFile() with std::ofstream
writeToFile( m_filename, m_stream, true );
}
template< typename T >
Log & operator<<( const T & p_value )
{
m_stream << p_value;
return *this;
}
private:
std::string m_filename;
std::ostringstream m_stream;
};
So this way I am able to log like this:
Log() << "My message in the log with numbers " << 1 << 2 << 3 << " and so on...";
Log( "other.log" ) << "Log in another file eventually...";
My current approach is to use a kind of dependency injection, using C++ strengths instead of magic. It does not require on anything specific to C++11 (except that __thread which is an extension could be replaced by thread_local if you wished to be Standard).
class LoggerEngine {
public:
static LoggerEngine* Current() { return CurrentE; }
virtual bool isActive(Level) { return true; }
virtual void log(char const* function,
char const* file,
int line,
std::string message) = 0;
// cuz' decorators rock
LoggerEngine* previous() const { return _previous; }
protected:
LoggerEngine(): _previous(CurrentE) { CurrentE = this; }
~LoggerEngine() { CurrentE = _previous; }
private:
static __thread LoggerEngine* CurrentE;
LoggerEngine* const _previous;
}; // class LoggerEngine
// in some .cpp file:
__thread LoggerEngine* LoggerEngine::CurrentE = 0;
And then, provide macros (to capture function, file and line):
#define LOG(L_, Message_) \
do { if (LoggerEngine* e = LoggerEngine::Current() and e->isActive(L_)) { \
std::ostringstream _28974986589657165; \
_28974986589657165 << Message_; \
e->log(__func__, __FILE__, __LINE__, _28974986589657165.str()); \
}} while(0);
However it could certainly be made better by using shims instead, because even though it prevents any computation in case the level is not active it still requires formatting of the full message (and the necessary memory allocation) even if it is going to truncate the message anyway (for example because it uses fixed-size buffers) and does not easily allow customization of the formatting.
The combination of stacking engines (and popping them off automatically using RAII) with thread-local behavior is really pretty neat. Most code only ever see an interface, without having to thread it by (cool when you have 4/5 different engines), and any level of the stack can switch the engine to something more appropriate.
There is one caveat, as is, no logging occurs before a first Engine is defined. For this reason I've often thought of defaulting to writing to the console if no engine is setup but... I've mostly changed my style to avoid computation before main is called since I cannot dependency-inject during this phase (and it's awkward if an exception fires...)
Usage is like this:
void benchmark() {
LOG(INFO, "Hello, World!");
Timer t;
{
MySinkLogger const _; (void)_; // a logger with "isActive" always false
for (size_t i = 0; i != 10000; ++i) {
LOG(INFO, "Flood!");
}
}
LOG(INFO, "Elapsed: " << t.elapsed());
}
int main() {
MyFileLoggerEngine const _("somefile.log"); (void)_; // a file logger
benchmark();
}
And normally this could create a file "somefile.log" containing:
2013-10-03T18:38:04.645512 mylaptop INFO <test.cpp#42> Hello, World!
2013-10-03T18:38:04.865765 mylaptop INFO <test.cpp#47> Elapsed: 0.220213s
Is it possible to redirect standard output to the output window from Visual Studio?
I use OutputDebugString in my program, but I use some libraries that have output debug messages with printf's or cout's.
From Redirecting cerr and clog to OutputDebugString():
#include <ostream>
#include <Windows.h>
/// \brief This class is derives from basic_stringbuf which will output
/// all the written data using the OutputDebugString function
template<typename TChar, typename TTraits = std::char_traits<TChar>>
class OutputDebugStringBuf : public std::basic_stringbuf<TChar,TTraits> {
public:
explicit OutputDebugStringBuf() : _buffer(256) {
setg(nullptr, nullptr, nullptr);
setp(_buffer.data(), _buffer.data(), _buffer.data() + _buffer.size());
}
~OutputDebugStringBuf() {
}
static_assert(std::is_same<TChar,char>::value ||
std::is_same<TChar,wchar_t>::value,
"OutputDebugStringBuf only supports char and wchar_t types");
int sync() try {
MessageOutputer<TChar,TTraits>()(pbase(), pptr());
setp(_buffer.data(), _buffer.data(), _buffer.data() + _buffer.size());
return 0;
}
catch(...) {
return -1;
}
int_type overflow(int_type c = TTraits::eof()) {
auto syncRet = sync();
if (c != TTraits::eof()) {
_buffer[0] = c;
setp(_buffer.data(), _buffer.data() + 1, _buffer.data() + _buffer.size());
}
return syncRet == -1 ? TTraits::eof() : 0;
}
private:
std::vector<TChar> _buffer;
template<typename TChar, typename TTraits>
struct MessageOutputer;
template<>
struct MessageOutputer<char,std::char_traits<char>> {
template<typename TIterator>
void operator()(TIterator begin, TIterator end) const {
std::string s(begin, end);
OutputDebugStringA(s.c_str());
}
};
template<>
struct MessageOutputer<wchar_t,std::char_traits<wchar_t>> {
template<typename TIterator>
void operator()(TIterator begin, TIterator end) const {
std::wstring s(begin, end);
OutputDebugStringW(s.c_str());
}
};
};
Then:
int main() {
#ifndef NDEBUG
#ifdef _WIN32
static OutputDebugStringBuf<char> charDebugOutput;
std::cerr.rdbuf(&charDebugOutput);
std::clog.rdbuf(&charDebugOutput);
static OutputDebugStringBuf<wchar_t> wcharDebugOutput;
std::wcerr.rdbuf(&wcharDebugOutput);
std::wclog.rdbuf(&wcharDebugOutput);
#endif
#endif
...
// Will be displayed in the debugger
std::cerr << "Error: something bad happened" << std::endl;
...
}
You might want to use it with
IsDebuggerPresent()
so that it still outputs to console when not run from the Visual Studio debugger.
Straightforward standard output redirection will not work, as there is no handle corresponding to OutputDebugString. However, there should be a way:
It could be done by redirecting standard output to a pipe, and then creating a thread which would read the pipe and print anything read from it using OutputDebugString.
Note: I was contemplating for a long ago to implement this, as I am facing exactly the same problem as you do (some libraries using printf or fprintf(stderr....). However, I never really did this. I have always ended modifying the libraries instead, and therefore I do not have a working implementation, but I think it should be feasible in principle.
Yes. I'm assuming that you're working on a Win32 GUI application.
Your C implementation defines three handles for standard input, standard output, and standard error. Win32 defines equivalent handles, which define where the actual physical input/output will appear. C functions, such as 'printf', use these Win32 handles to perform I/O. Basically, you have to create a console for output, and then redirect where the Win32 standard output points to. And then getting the handle to the C standard output and associating this with the Win32 standard output.
This link contains more information on how to do this:
You'll need to add two new files to your application (the link contains the listings).
I was using Visual Studio 2012 and also wanted to redirect standard output and standard error while debugging a script, a C++ program or a MSTest DLL without having to change the source code itself. My approach, that I finally came up with, was to capture the output using sort of an intermediate program.
Create C# Windows Console Application
Take the following C# code and create/compile a Windows C# .NET Console Application:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading;
namespace OutputDebugStringConsole
{
class OutputDebugStringConsole
{
private static void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
{
if (null != outLine.Data)
{
Trace.WriteLine(outLine.Data);
Trace.Flush();
Console.WriteLine(outLine.Data);
}
}
static void Main(string[] args)
{
if (args.Length == 0)
{
return;
}
try
{
Process p = new Process();
p.StartInfo.FileName = args[0];
p.StartInfo.Arguments = String.Join(" ", args, 1, args.Length - 1);
Trace.WriteLine("Calling " + p.StartInfo.FileName + " " + p.StartInfo.Arguments);
p.StartInfo.WorkingDirectory = Directory.GetCurrentDirectory();
p.StartInfo.CreateNoWindow = true;
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.OutputDataReceived += new DataReceivedEventHandler(OutputHandler);
p.ErrorDataReceived += new DataReceivedEventHandler(OutputHandler);
p.Start();
p.BeginOutputReadLine();
p.BeginErrorReadLine();
p.WaitForExit();
// Call WaitForExit() AFTER I know the process has already exited by a successful return from WaitForExit(timeout).
// This causes the code that reads all remaining pending async data to be executed.
// see https://groups.google.com/d/msg/microsoft.public.dotnet.framework.sdk/jEen9Hin9hY/FQtEhjdKLmoJ
Thread.Sleep(100);
p.WaitForExit();
p.Close();
}
catch (Exception e)
{
Trace.WriteLine(e.ToString());
Console.WriteLine("{0} Exception caught.", e);
}
}
}
}
I used Trace.WriteLine() instead of Debug.WriteLine(), because it then works also in the release version of the above code.
Use Application in Visual Studio Project Debugging
NOTE: If you have chosen .NET 4/4.5 and you are capturing the output of unmanaged code, you need to select Mixed as your Debugging/Debugger Type in your Project Settings. Otherwise (with Auto) you may get an unhandled KernelBase.dll exception.
Now you can use the application by putting the newly created
OutputDebugStringConsole.exe
into Debugging/Command properties and
"$(TargetPath)" [ARGS ...]
or e.g. if it is the MSTest DLL file:
"$(DevEnvDir)CommonExtensions\Microsoft\TestWindow\vstest.console.exe"
/Platform:x86 $(TargetPath)
into your Debugging/Arguments of the application you want to debug. The quotation marks in the command arguments are necessary to handle spaces in your application's path.
Please take this only as an example what the application can be used for. I'm aware that the Visual Studio 2012 Test Explorer does offer a very nice way to run MSTest DLL files and get the output in a structured way.
I'm developing a C api for some functionality written in C++ and I want to make sure that no exceptions are propagated out of any of the exported C functions.
The simple way to do it is making sure each exported function is contained in a:
try {
// Do the actual code
} catch (...) {
return ERROR_UNHANDLED_EXCEPTION;
}
Let's say I know one exception that is often missed inside the C++ code is std::bad_alloc and I want to treat it specially I'd write something like this instead:
try {
// Run the actual code
} catch (std::bad_alloc& e) {
return ERROR_BAD_ALLOC;
} catch (...) {
return ERROR_UNHANDLED_EXCEPTION;
}
Is it possible to decompose this in some clever way so that I can globally treat some errors differently without adding a new catch statement for the exception handler around every exported function?
I'm aware of that this is possible to solve using the preprocessor, but before going down that road, I'd make sure there is no other way to do it.
You can use only one handler function for all possible exceptions, and call it from each or your API implementation functions, as below:
int HandleException()
{
try
{
throw;
}
// TODO: add more types of exceptions
catch( std::bad_alloc & )
{
return ERROR_BAD_ALLOC;
}
catch( ... )
{
return ERROR_UNHANDLED_EXCEPTION;
}
}
And in each exported function:
try
{
...
}
catch( ... )
{
return HandleException();
}
There already is a good answer. But just FYI, its called 'exception-dispatcher' idiom, see C++ FAQ.
What about:
try{
//Your code here
} catch(std::exception e)
{
return translateExceptionToErrorCode(e);
} catch(...)
{
return UNKNOWN_EXCEPTION_THROWN;
}
Jem answer is a little more simpler than this solution. But it is possible to substitute the use of a preprocessor macro with the use of templates. Something like this (more refinements you could made):
template <class T, void (T::*FUNC)()>
class CatchWrapper
{
public:
static void WrapCall(T* instance)
{
try
{
(instance->*FUNC)();
}
catch (std::bad_alloc&)
{
// Do Something 1
}
catch (std::exception& e)
{
// Do Something 2
}
catch (...)
{
// Do Something 3
}
}
};
class Foo
{
public:
void SomeCall()
{
std::cout << "Do Something" << std::endl;
}
};
int main(int argc, char* argv[])
{
Foo i;
CatchWrapper<Foo, &Foo::SomeCall>::WrapCall(&i);
return 0;
}
Do not ever use catch(...), unless you plan on more or less immediately re-throwing. You will certainly lost any error information you might have had to help you figure out the cause of the error.
I like your second scheme a little better - catch a known set of exceptions, ideally because they are the only ones your code will throw, and let the rest through - allowing the app to crash is possibly the best thing to do since you have invoked unknown behaviour it is best to "crash responsibly".
It would be a shame to loose error information at the language boundary. You really should try to translate all exceptions into an error code usable from C.
How you do it really depends on what your exception classes look like. If you control your exception class hierarchy, you can ensure that each class provides a translation using a virtual method. If not, you may still find it practical to use a translator function and test the types of the 'std::exception'-derived exception it receives to translate it into an error code, much like Jem suggested (remember: thrown exceptions will hurt performance anyway, so don't worry about the translation being slow).