I try to cascade exception in Poco.
void debug() {
try {
...
xmlFile.parseDocument(*_sim);
...
}
} catch (Poco::Exception& error) {
std::cout << "I'm here" << endl;
std::cout << "Error : " << error.displayText() << std::endl;
}
}
void XMLParser::parseDocument(Manager &manager) {
...
try {
Poco::XML::NodeList* policyList = root->childNodes();
for (uint node=0; node < policyList->length(); node++)
if (policyList->item(node)->hasChildNodes())
manager.insertRule(parseRule(node, policyList->item(node)));
} catch(Poco::Exception& error) {
std::cout << "Error : " << error.displayText() << std::endl;
error.rethrow();
}
}
Rule* XMLParser::parseRule(int flowID, Poco::XML::Node* rule) throw() {
....
if (tLink._srcPort < 0)
throw new Poco::Exception("Source Port isn't valid");
....
}
The deepest exception are thrown, but it does not continue to outer functions.
The program is terminated. Why?
You throw a Poco::Exception pointer so you can not catch it by reference.
Remove 'new'. This should work:
....
if (tLink._srcPort < 0)
throw Poco::Exception("Source Port isn't valid");
....
Related
I don't have much knowledge of exception.
I have two files task.cpp, main.cpp. Inside task.cpp file, I have a lot try/catch statements. I want to remove all the generic handlers for things like ..., std::exception etc., they are just printing the error, and I want to create just a single error handler of this kind and reside it inside main.cpp. How can I do it ?
These are some part of task.cpp & main.cpp file.
I want to remove catch (...) , catch (Exception const& _exception) from task.cpp file as they are used at multiple steps and create repetitive code
try
{
if (!stack.parseAndAnalyze(src.first, src.second))
successful = false;
else
stack.optimize();
}
catch (Exception const& _exception)
{
serr() << "Exception in assembler: " << boost::diagnostic_information(_exception) << endl;
return false;
}
catch (std::exception const& _e)
{
serr() <<
"Unknown exception during compilation" <<
(_e.what() ? ": " + string(_e.what()) : ".") <<
endl;
return false;
}
catch (...)
{
serr() << "Unknown exception in assembler." << endl;
return false;
}
}
if (_language != yul::AssemblyStack::Language::Ewasm && _targetMachine == yul::AssemblyStack::Machine::Ewasm)
{
try
{
stack.translate(yul::AssemblyStack::Language::Ewasm);
stack.optimize();
}
catch (Exception const& _exception)
{
serr() << "Exception in assembler: " << boost::diagnostic_information(_exception) << endl;
return false;
}
catch (std::exception const& _e)
{
serr() <<
"Unknown exception during compilation" <<
(_e.what() ? ": " + string(_e.what()) : ".") <<
endl;
return false;
}
catch (...)
{
serr() << "Unknown exception in assembler." << endl;
return false;
}
sout() << endl << "==========================" << endl;
sout() << endl << "Translated source:" << endl;
sout() << stack.print() << endl;
}
try
{
object = stack.assemble(_targetMachine);
object.bytecode->link(m_options.linker.libraries);
}
catch (Exception const& _exception)
{
serr() << "Exception while assembling: " << boost::diagnostic_information(_exception) << endl;
return false;
}
catch (std::exception const& _e)
{
serr() << "Unknown exception during compilation" << (
_e.what() ? ": " + string(_e.what()) : "."
) << endl;
return false;
}
catch (...)
{
serr() << "Unknown exception while assembling." << endl;
return false;
}
And catch inside main.cpp file like this:
int main(int argc, char** argv)
{
try
{
setDefaultOrCLocale();
solidity::frontend::CommandLineInterface cli(cin, cout, cerr);
if (!cli.parseArguments(argc, argv) || !cli.readInputFiles() || !cli.processInput() || !cli.actOnInput())
return 1;
return 0;
}
catch (boost::exception const& _exception || Exception const& _exception || InternalCompilerError const& _exception
|| smtutil::SMTLogicError const& _exception)
{
cerr << "Uncaught exception" << boost::diagnostic_information(_exception) << endl;
return 1;
}
catch (std::exception const& _e)
{
cerr() << "Uncaught exception" << (_e.what() ? ": " + string(_e.what()) : ".") << endl;
return 1;
}
catch (Exception const& _exc)
{
cerr() << string("Failed to import AST: ") << _exc.what() << endl;
return 1;
}
catch (...)
{
cerr << "Uncaught exception" << endl;
return 1;
}
}
std::nested_exceptions are nice when all you want to do is calling what(), but accessing the interface of other exception types gets ugly.
Let us suppose I have two exception classes which store some additional information:
/* CODE BLOCK 1 */
class ErrorI : public std::runtime_error {
public:
ErrorI(int a_integer) : std::runtime_error{"ErrorI"}, integer{a_integer} {}
int integer;
};
class ErrorD : public std::runtime_error {
public:
ErrorD(double a_real) : std::runtime_error{"ErrorD"}, real{a_real} {}
double real;
};
Without nested exceptions, we can access the member variables in the try/catch block:
/* CODE BLOCK 2 */
int main()
{
try {
/* do stuff */;
}
catch(const ErrorI& ee){
std::cout << " Value: " << ee.integer << std::endl;
}
catch(const ErrorD& ee){
std::cout << " Value: " << ee.real << std::endl;
}
}
But if we want to unwrap a std::nested_exception, things are not so straightforward. We need to define a function which will be called recursively, which should look like this:
/* CODE BLOCK 3 */
void process_exception(const std::exception& e, int level=0) {
try {
std::rethrow_if_nested(e);
}
catch(const std::exception& e) {
process_exception(e, level+1);
}
/* ... process the top-most (latest) exception ... */
}
Unfortunately, for processing the top-most exception, we cannot use the try/catch syntax in Code Block 2: if we rethrow e, it will be truncated to an std::exception, and we will lose all the additional information. EDIT: This is not true if std::rethrow_exception and std::exception_ptr are used.
So we're back to the problem of good-ole dynamic type-checking, with all that it entails (see this for example).
Derive all the exceptions from a common base class with the desired interface. This includes approaches like the Visitor pattern. This is neat, but not good if the exception classes are provided by a external library.
Using dynamic_cast:
/* CODE BLOCK 4 */
if (auto p = dynamic_cast<ErrorI const*>(&e)) {
std::cout << " Value: " << p->integer << std::endl;
}
else if (auto p = dynamic_cast<ErrorD const*>(&e)) {
std::cout << " Value: " << p->real << std::endl;
}
???
My only option seems to resort to 2. I would love to hear if there is any other suggestion.
With the help of std::exception_ptr, you might do something like:
void print_exception(const std::exception_ptr& eptr, int level = 0)
{
try
{
std::rethrow_exception(eptr);
}
catch (const ErrorI& e)
{
std::cerr << std::string(level, ' ') << "exception: " << e.what() << ": " << e.integer << std::endl;
}
catch (const ErrorD& e)
{
std::cerr << std::string(level, ' ') << "exception: " << e.what() << ": " << e.real << std::endl;
}
catch (const std::exception& e)
{
std::cerr << std::string(level, ' ') << "exception: " << e.what() << std::endl;
}
}
// prints the explanatory string of an exception. If the exception is nested,
// recurses to print the explanatory of the exception it holds
void print_exception_rec(const std::exception_ptr& eptr, int level = 0)
{
print_exception(eptr, level);
try {
try {
std::rethrow_exception(eptr);
}
catch (const std::exception& e)
{
std::rethrow_if_nested(e);
}
} catch(const std::exception&) {
print_exception_rec(std::current_exception(), level+1);
} catch(...) {}
}
Demo
I've been trying to output "Queue is full" which was declared in my other code. How do I catch this?
this is my main
int main() {
IntQueue iQueue(5);
try {
cout << "Enqueuing 5 items...\n";
// Enqueue 5 items.
for (int x = 0; x < 5; x++)
iQueue.enqueue(x);
} catch (...) {
// Attempt to enqueue a 6th item.
cout << "Now attempting to enqueue again...\n";
iQueue.enqueue(5);
}
and this is my other code
if (isFull())
throw std::runtime_error("Queue is full");
else {
cout << "Enqueueing: " << num << endl;
// Calculate the new rear position
rear = (rear + 1) % queueSize;
// Insert new item
queueArray[rear] = num;
// Update item count
numItems++;
}
Here is how you catch an exception and print its message:
try {
// ...
} catch (std::runtime_error const& e) {
std::cout << e.what() << '\n'; // or std::cerr, std::perror, or smth else
}
Any code under the catch block is meant to catch any exception thrown in the try block, which means you should write any code that could throw exceptions in it:
try {
// trying to enqueue 6 items, which is above limit.
for (int x = 0; x < 6; x++) {
iQueue.enqueue(x);
}
} catch (exception e) {
cout << e.what() << '\n';
}
I was looking similar to finally for c++ but I came across RAII. I have a small confusion though. If I have some common code I want to run in case of any exception,
Example: std::cout << "exception occured" << std::endl;
Is there a way to do that instead of copy the same code?
#include <iostream>
int main()
{
bool firstException = false;
try
{
if(firstException)
throw std::invalid_argument("the truth is out there!!");
else
throw std::domain_error("Bazzinga");
}
catch (std::invalid_argument const& e)
{
std::cout << e.what() << std::endl;
std::cout << "exception occured" << std::endl;
}
catch (std::domain_error const& e)
{
std::cout << e.what() << std::endl;
std::cout << "exception occured" << std::endl;
}
}
I got now what molbdnilo was talking about in the comment.
The code below has the answer. :) :D
#include <iostream>
int main()
{
bool firstException = true;
try
{
if(firstException)
throw std::invalid_argument("the truth is out there!!");
else
throw std::invalid_argument("Bazzinga");
}
catch (std::exception const& e)
{
std::cout << e.what() << std::endl;
std::cout << "exception occured" << std::endl;
}
}
Whenever I input anything other than an integer, I was hoping for the catch block to execute but instead I get this error:
Unhandled exception at 0x002D0C39 in A03.exe: Stack cookie instrumentation code detected a stack-based buffer overrun. occurred
which takes me to:
Exception thrown at 0x76D44192 in A03.exe: Microsoft C++ exception: std::invalid_argument at memory location 0x0116D83C.
Unhandled exception at 0x000608B9 in A03.exe: Stack cookie instrumentation code detected a stack-based buffer overrun.
I've tried varieties of catch blocks and exceptions with the same error. Can someone tell me what I'm doing wrong? Thank you!
Here is the code:
int main() {
while (true) {
std::string input;
int num = 0;
std::cout << "What number do you want to show?";
std::cin >> input;
try
{
num = std::stoi(input);
if (num >= 0 && num < 10)
{
std::cout << "FILLER: This will draw the number";
exit(0);
}
else {
std::cout << "FILLER: This is the else";
exit(1);
}
}
catch (std::runtime_error e)
{
std::cout << e.what();
//std::cout << "That is not a valid number." << '\n';
}
}
return 0;
}
UPDATE: Edited the exception handler, but still erroring:
int main() {
while (true) {
std::string input;
int num = 0;
std::cout << "What number do you want to show?";
std::cin >> input;
try
{
num = std::stoi(input);
if (num >= 0 && num < 10)
{
std::cout << "FILLER: This will draw the number";
exit(0);
}
else {
std::cout << "FILLER: This is the else";
exit(1);
}
}
catch (std::invalid_argument &e)
{
std::cout << e.what();
//std::cout << "That is not a valid number." << '\n';
}
}
return 0;
}
The exception that this function throws is std::invalid_argument, which have the following inheritance connections: std::exception <- std::logic_error <-std::invalid_argument. This means you can use any of the above as the catch type (and also ...), to catch the exception. std::runtime_error is not one of the options (std::exception <- std::runtime_error).
Change your catch section to:
catch (std::invalid_argument &e) {
std::cout << e.what();
//std::cout << "That is not a valid number." << '\n';
}
Read About:
std::invalid_argument
std::runtime_error
std::exception - Exceptions tree