I'm basically lost on this one. I've looked at Boost doc plus searching on SO, but I don't seem to find a thing. Assuming a class modelling Fraction, I want to throw an exception when divider is to be set to 0.
void Fraction::setQ(int q) {
if (q == 0){
throw new std::logic_error("Divider must not be null");
}else{
q_ = q;
}
}
And this code is tested with this block of code
BOOST_AUTO_TEST_CASE( NonZeroDivider ){
BOOST_CHECK_THROW(
f->setQ(0),
std::logic_error
);
}
But when boost should catch the exception, it doesn't and prints an error followed by a failure
unknown location(0): fatal error in "NonZeroDivider": unknown type
If you could help me on this one, I've tried BOOST_CHECK_EXCEPTION (with necessary editions) but no idea. Always the same behavior. Thanks!
Your code doesn't throw an exception (std::logic_error), it throws a pointer to a dynamically allocated exception (std::logic_error*); see throw new std::exception vs throw std::exception.
The fix is to remove the new keyword:
throw new std::logic_error("Divider must not be null");
~~~~
Related
I have some if, else_if, else blocks of code for different user input. The else at the end is for an invalid entry from the user. This is all part of a try block.
In the case the user makes an invalid entry I have to throw an exception. My prof already has this code prepared for the catch:
catch (char const* errormsg ) // for invalid item case
{code goes here }
Right now my else statement just looks like this:
else {
throw item;
}
I'm new to exception handling. Can somebody explain what I need to throw for the catch to catch it?
Since the code is designed to catch const char*s, and the argument has been called errormsg, it seems like the intent was for the exception object to be a C-style string containing the error message.
A string literal fits the bill:
throw "This is a description of the problem";
Note that this is bad practice; you should throw something of a descriptive type that derives from std::exception as a matter of convention.
I'm working on exception handling and right now I'm stuck on a problem I'm working on out of my book. What I'm trying to do is add an try-catch block inside my main function to catch an exception that is thrown by a function that I am using. Here are snippets of where I am having trouble on.
EmptyStackPopException is an empty Exception class that I put into my stack.h file that can be seen here:
class EmptyStackPopException {
};
Here is the function that is supposed to throw this Exception.
T Stack<T>::pop( ) throw (EmptyStackPopException)
{
if (isEmpty( ))
{
throw EmptyStackPopException();
}
T result = top->getData( );
Node<T> *discard;
discard = top;
top = top->getLink( );
delete discard;
return result;
}
Here is a snippet of my main function where the exception is supposed to be caught:
try {
cout << s.pop( );
} catch (EmptyStackPopException) {
cout << "EmptyStackPopException: You didn't enter anything in." << endl;
}
Now the issue that I'm having is I cannot compile because of these following errors:
..\assignment8\main.cpp(29) : error C2061: syntax error : identifier 'EmptyStackPopException'
..\assignment8\main.cpp(29) : error C2310: catch handlers must specify one type
..\assignment8\main.cpp(32) : error C2317: 'try' block starting on line '27' has no catch handlers
I'm pretty sure that the only error I have at the moment is in the main function, EmptyStackPopException is not able to be detected in the client program which causes the last two errors.
You must specify a type with your catch statement. This should fix the three syntax errors your presented
try {
cout << s.pop( );
} catch (EmptyStackPopException& exception) {
cout << "EmptyStackPopException: You didn't enter anything in." << endl;
}
You needed to create 'exception'.
If including your EmptyStackPopException header doesn't work (based on context I'm not sure it will), the problem might be based on circular dependency, which means that two header files are including each other. I can't tell from context but this sometimes gives me the "syntax error : identifier" error.
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!
I've got this code snnipet (the whole program compiles and links correctly):
...
try
{
boost::python::exec_file(
"myscript.py", // this file contains a syntax error
my_main_namespace,
my_local_namespace
);
return true;
}
catch(const boost::python::error_already_set &)
{
PyObject *ptype, *pvalue, *ptraceback;
PyErr_Fetch(&ptype, &pvalue, &ptraceback);
// the next line crashes on syntax error
std::string error = boost::python::extract<std::string>(pvalue);
...
}
The file that the program tries to execute has a syntax error, so an exception is thrown. When the program tries to get the error message crashes...
The code works well with run-time errors but somehow crashes with syntax errors.
How can i get the error string with this kind of errors?
Thanks in advance
From the documentation of PyErr_Fetch: "The value and traceback object may be NULL even when the type object is not". You should check whether pvalue is NULL or not before trying to extract the value.
std::string error;
if(pvalue != NULL) {
error = boost::python::extract<std::string>(pvalue);
}
If you want to check whether the exception is a SyntaxError you can compare ptype against the exception types listed here.
To answer anymore specifically I would need a backtrace from the point where it crashed.
Edit
pvalue is an exception object, not a str instance so you should use PyObject_Str to get the string representation of the exception.
You may need to call PyErr_NormalizeException first to turn pvalue into the correct exception type.
I have come to something of a crossroads. I recently wrote a 10,000 line application with no TDD (a mistake I know). I definitely ran into a very large amount of errors but now I want to retrofit the project. Here is the problem I ran into though. Lets take a example of a function that does division:
public int divide (int var1, int var2){
if (var1 == 0 || var2 == 0)
throw new RuntimeException("One of the parameters is zero");
return var1 / var2;
}
In this situation I'm throwing a runtime error so that I can fail and at least find out that my code is broke somewhere. The question is 2 fold. First, am I making the correct use of the exceptions here? Secondly how do I write a test to work with this exception? Obviously I want it to pass the test but in this case it's going to throw an exception.
Not too sure how one would work that out. Is there a different way that this is generally handled with TDD?
Thanks
First, your first argument (the numerator) being zero probably shouldn't cause an exception to be thrown. The answer should just be zero. Only throw an exception when a user tries to divide by zero.
Second, there are two ways (using JUnit) to test that exceptions are thrown when they should be. The first "classic" method:
#Test
public void testForExpectedExceptionWithTryCatch()
throws Exception {
try {
divide (1, 0);
fail("division by zero should throw an exception!");
} catch (RuntimeException expected) {
// this is exactly what you expect so
// just ignore it and let the test pass
}
}
The newer method in JUnit 4 uses annotations to cut down on the amount of code you need to write:
#Test(expected = RuntimeException.class)
public void testForExpectedExceptionWithAnnotation()
throws Exception {
divide (1, 0);
}
Here, because we added (expected = RuntimeException.class) to the annotation, the test will fail if the call to divide doesn't throw a RuntimeException.
To answer your first question:
If it's quite likely the denominator argument to divide will be 0 then you shouldn't be using exception handling to trap the error. Exceptions are expensive and shouldn't be used to control program flow. So you should still check, but return an error code (or use a nullable type as the return value) and your calling code should check on this and handle it appropriately.
public int? divide (int var1, int var2)
{
if (var2 == 0)
{
return null; // Calling method must check for this
}
return var1 / var2;
}
If zeros are truly the exception - e.g. there should be no way that they can be passed - then do as you do now.
To answer your second question:
In your test methods that check the failure code you need an exception handler:
try
{
divide (1, 0);
// If it gets here the test failed
}
catch (RuntimeException ex)
{
// If it gets here the test passed
}
I am not answering your main question.
I would suggest using ArgumentException instead of RuntimeException.
EDIT: I am assuming .net :)
Your question was language-agnostic, so my answer might not apply, but NUnit in .NET (and I believe JUnit too) have a specific notation for testing exceptions. In NUnit, your test would look like this:
[Test]
[ExpectedException(typeof(RuntimeException))]
public void DivideByZeroShouldThrow()
{
divide(1,0);
}
The test will fail if the right type of exception is not thrown during the execution.
The try/catch approach works too, and has its advantages (you can pinpoint exactly where you expect the exception to occur), but it can end up being pretty tedious to write.
The first question is answered well by ChrisF and Bill the Lizard.
I just want to add an alternative to the exception test, with C++11 you can use a lambda directly in your test.
Assert::ExpectException<std::invalid_argument>([] { return divide(1,0); }, "Division by zero should throw an exception.");
This is equivalent to:
try
{
divide(1,0);
Assert::Fail("Division by zero should throw an exception.");
}
catch(std::invalid_argument)
{
//test passed
}