I have the following chunk of code in my constructor (This is just an example, the question isn't about split, rather about throwing a generic exception. Also, Boost library can't be used.
Transfer::Transfer(const string &dest){
try{
struct stat st;
char * token;
std::string path(PATH_SEPARATOR) // if it is \ or / this macro will solve it
token = strtok((char*)dest.c_str(), PATH_SEPARATOR) //
while(token != NULL){
path += token;
if(stat(path.c_str(), &st) != 0){
if(mkdir(path.c_str()) != 0){
std:string msg("Error creating the directory\n");
throw exception // here is where this question lies
}
}
token = strtok(NULL, PATH_SEPARATOR);
path += PATH_SEPARATOR;
}
}catch(std::exception &e){
//catch an exception which kills the program
// the program shall not continue working.
}
}
What I want is to throw an exception if the directory does not exist and it can't be created. I want to throw a generic exception, how could I do it in C++?
PS: dest has the following format:
dest = /usr/var/temp/current/tree
Please check this answer. This explains how to use your own exception class
class myException: public std::runtime_error
{
public:
myException(std::string const& msg):
std::runtime_error(msg)
{}
};
void Transfer(){
try{
throw myException("Error creating the directory\n");
}catch(std::exception &e){
cout << "Exception " << e.what() << endl;
//catch an exception which kills the program
// the program shall not continue working.
}
}
Also, if you don't want your own class, you can do this simply by
throw std::runtime_error("Error creating the directory\n");
Your usage of strtok is incorrect - it needs a char* because it modifies the string, but it is not permitted to modify the results of a .c_str() on a std::string. The need to use a C style cast (which here is performing like a const_cast) is a big warning.
You can neatly sidestep this and the path separator portability stuff by using boost filesystem, which is likely to appear in TR2 whenever that's release. For example:
#include <iostream>
#include <boost/filesystem.hpp>
int main() {
boost::filesystem::path path ("/tmp/foo/bar/test");
try {
boost::filesystem::create_directories(path);
}
catch (const boost::filesystem::filesystem_error& ex) {
std::cout << "Ooops\n";
}
}
Splits the path on the platform's separator, makes the directories if needed or throws an exception if it fails.
Related
When delivering an API to you often have to declare error codes (most often as int) and later you often want to provide a function converting a int error code to std::string to be able to report the error to the user in a smart way.
I found some posts on how to maintain the int/std::string mapping programmatically, like this one: Mapping error codes to string in C++
Now, I was wondering, why not simply return a std::string rather than a int? Empty string would mean no error, anything else would mean error + provide a human readable message.
Let's obviously assume you don't care about memory usage and performances (your API has functions not called that often and time of execution is not critical).
If you need the client to be able to do some specific operations programmatically, error codes could be declared as constants. But you don't need any int to std::string mapping anymore. As an example, it would be:
Declaration:
static const std::string successMessage;
static const std::string fileDoesNotExistMessage;
static const std::string internalErrorMessage;
std::string openFile( const std::string& fileName );
Implementation:
static const std::string successMessage = "";
static const std::string fileDoesNotExistMessage = "File does not exist";
static const std::string internalErrorMessage = "Internal error";
std::string openFile( const std::string& fileName )
{
if ( ... ) // test file existance
{
if ( ... ) // internal tests
return internalErrorMessage;
else
return successMessage;
}
else
{
return fileDoesNotExistMessage ;
}
}
API user can then do:
int main()
{
std::string error = openFile( "file.txt" );
if ( error.empty() )
{
std::cout << "File was successfully opened" << std::endl;
}
else if ( error == fileDoesNotExistMessage )
{
// specific error handling
}
else
{
std::cout << "Unable to open file, error reported is " << error << std::endl;
}
}
Advantages:
No risk to have a int/std::string broken mapping
Easy to add error codes on the fly
Easy to maintain
There must be disavantages, because I know no open source library using this approach...any idea why?
Why not go one stage further and do the Right Thing(tm)?
Report errors with exceptions. It's what they're for.
example:
struct file_does_not_exist : std::runtime_error
{
using std::runtime_error::runtime_error;
};
struct internal_error : std::runtime_error
{
using std::runtime_error::runtime_error;
};
void openFile( const std::string& fileName )
{
if (!fileExists())
throw file_does_not_exist(fileName + " does not exist");
if (!internal_tests(fileName))
throw internal_error("internal tests failed");
doLogic();
}
user code now becomes:
try {
openFile("xyz.txt");
do_other_logic();
...
}
catch(const std::exception& e)
{
std::cerr << "failed because: " << e.what() << std::endl;
}
A complete example that demonstrates why exceptions are the Right Thing
#include <iostream>
#include <stdexcept>
#include <exception>
#include <string>
#include <fstream>
// define our program's exceptions, deriving from standard types
struct failed_to_open : std::runtime_error
{
using std::runtime_error::runtime_error;
};
struct database_op_failed : std::runtime_error
{
using std::runtime_error::runtime_error;
};
struct user_update_failed : std::runtime_error
{
using std::runtime_error::runtime_error;
};
// copied from cppreference.com
void print_exception(const std::exception& e, int level = 0)
{
std::cerr << std::string(level, ' ') << "exception: " << e.what() << '\n';
try {
std::rethrow_if_nested(e);
} catch(const std::exception& e) {
print_exception(e, level+1);
} catch(...) {}
}
void open_file(std::fstream& f, const std::string& filename)
{
throw failed_to_open(std::string("failed to open file " + filename));
}
struct database_connection
{
database_connection()
try {
open_file(_file, "database.txt");
}
catch(...) {
std::throw_with_nested(database_op_failed("database failed to create"));
}
std::fstream _file;
};
// note the use of function try blocks coupled with
// throw_with_nested to make exception handling *clean and easy*
void update_user_age(const std::string& name, int newage)
try {
database_connection d;
// d.update_record(...)
// ... RAII
}
catch(...) {
std::throw_with_nested(user_update_failed("failed to update user " + name
+ " to age " + std::to_string(newage)));
}
// only one try/catch in the whole program...
int main()
{
try {
update_user_age("bob", 30);
// ... lots more log here with no need to check errors
}
catch(const std::exception& e) {
// ...which completely explains the error
print_exception(e);
return(100);
}
return 0;
}
expected output:
exception: failed to update user bob to age 30
exception: database failed to create
exception: failed to open file database.txt
This could be useful to a user, but not to a dev.
Given any error, I'd like to easily find the spot responsible for it. Can you guarantee the message will remain unchanged, so a future search will point to the right spot? It's much easier to get that with enums - the message can be changed with no real harm.
You should not underestimate the performance issue. Comparison, copying, allocation - it costs. If you really, really don't care, simply create a struct with both error code and string message. Or throw an exception.
What are the best practices for catching all errors during file IO in C++? More specifically, what are the best practices for dealing with errors that could potentially arise with ios objects? For example, the following program reads a file from disk and prints it:
#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
#include <exception>
#include <stdexcept>
// Defines a custom exception
struct MyException : public std::exception {
std::string s;
MyException(std::string s_) : s(s_) {};
const char * what () const throw () {
return ("MyException: " + s).c_str();
}
};
// Prints out nested exceptions
void print_exception(std::exception const & e, size_t const level = 0) {
std::cerr << std::string(level, ' ') << "exception: " << e.what() << '\n';
try {
std::rethrow_if_nested(e);
} catch(const std::exception& e) {
print_exception(e, level+1);
} catch(...) {}
}
// Read the specified filename into a string
std::string read_into_string(std::string const & fname) {
// Create the file stream
std::ifstream fin;
fin.exceptions(std::ifstream::failbit | std::ifstream::badbit);
// Open the file
try {
fin.open(fname.c_str());
} catch(...) {
std::throw_with_nested(MyException(
"Unable to open the file: " + fname));
}
// Make sure to close out the file if there's a problem
try {
// Create the string stream
std::stringstream sin;
sin.exceptions(std::ifstream::failbit | std::ifstream::badbit);
// Put the file stream into a string stream
try {
sin << fin.rdbuf();
} catch(...) {
std::throw_with_nested(MyException(
"Error when pusing the file stream into the string stream"));
}
// Turn the string stream into a string
std::string str;
try {
str = sin.str();
} catch(...) {
std::throw_with_nested(MyException(
"Error converting the string stream into a string"));
}
// Close out the file
fin.close();
// Return the string;
return str;
} catch(...) {
// Close out the file
fin.close();
// Rethrow the exception
throw;
}
}
int main() {
try {
std::string str(read_into_string("file.txt"));
std::cout << str;
} catch(const std::exception& e) {
print_exception(e);
}
}
However, it seems very, very heavy. Basically, it seems like we have to check every time we touch an ios object since something could go wrong and it would help to know exactly where. In addition, the above code contains multiple file closes, one what everything works and one where there's an exception, which is undesirable. Finally, I didn't check the error status of the other ios objects such as cout, but technically since they're ios objects, couldn't they set a bad or fail bit as well that should be trapped? Do the string streams need to be closed out in case of an error?
Really, the core question is: what are the best practices for dealing with errors that could potentially arise with ios objects?
It's not common practice to enable .exceptions() on an I/O stream in C++. Most likely you learned some other language where they taught you to use exceptions for everything you can. Don't.
It' perfectly easy to handle errors on streams without exceptions: the stream will change from being truthy to being falsy. Additionally, unless you reset the failure bits, any operation on a falsy stream will have absolutely no effect.
Additionally, there is a method for dumping an entire input stream into an output stream.
// Read the specified filename into a string
std::string read_into_string(std::string const & fname) {
// Create the file stream
std::ifstream fin(fname.c_str());
std::ostringstream oss;
oss << fin.rdbuf();
if (!fin) throw MyException();
return oss.str();
}
However, you might want to rethink your need for input in a single stream. Usually I find a sequence of lines to be much more useful.
You can reduce the pain a little because:
you can call exceptions() on the stream after you've opened it
stream.close() is implicit in the destructor
-
std::string read_into_string(std::string const & fname) {
// Create the file stream
std::ifstream fin(fname.c_str());
try {
fin.exceptions(std::ifstream::failbit | std::ifstream::badbit);
} catch(...) {
std::throw_with_nested(MyException(
"Unable to open the file: " + fname));
}
// Create the string stream
std::stringstream sin;
try {
sin.exceptions(std::ifstream::failbit | std::ifstream::badbit);
sin << fin.rdbuf();
} catch(...) {
std::throw_with_nested(MyException(
"Error when pusing the file stream into the string stream"));
}
// this try is very pedantic, you probably don't need it since the only exception
// here will be std::bad_alloc
try {
return sin.str();
} catch(...) {
std::throw_with_nested(MyException(
"Error converting the string stream into a string"));
}
// RAII takes care of closing all the file handles for you
}
However most people would write the function more like this:
std::string read_into_string(std::string const & fname) {
try {
std::ifstream fin(fname.c_str());
fin.exceptions(std::ifstream::failbit | std::ifstream::badbit);
std::stringstream sin;
sin.exceptions(std::ifstream::failbit | std::ifstream::badbit);
sin << fin.rdbuf();
return sin.str();
} catch(...) {
std::throw_with_nested(MyException(
std::string("problem with file ") + fname));
}
}
in addition, MyException should probably be more like this:
struct MyException : public std::runtime_error {
MyException(const std::string& s_) : std::runtime_error(std::string("MyException:) +s_) {};
};
Because this way it's derived from runtime_error (which states what it actually is), and you're not returning a dangerous pointer into a temporary in the what() implementation.
I have written a class to control mandatory input on an istream, based on the original idea posted there: https://stackoverflow.com/a/14331519/3723423 . It verifies and skips mandatory formatting chars, a little bit like with scanf(), but with a stream semantic:
int country; string phone;
cin >> mandatory_input(" ( + ") >> country >> mandatory_input(" ) ") >> phone;
The class is consistent with standard istream operations, setting failbit in case of non compliant input, and throwing exceptions if and only if exceptions(istream::failbit); was set.
I have questions for improving error processing when class is used with exceptions:
Alternative 1: put error information in a static member. That's my current solution.
Alternative 2: throw my own exception class derived from istream::failure, with all information about error conditions. That would be the most elegant solution. Is there a way to throw my own exception AND set the failbit ? If I set failbit, an exception is thrown before I can throw my own. But if I don't set it, I'm not consistent with standard operations. (Edit: If I temporarily deactivate exceptions before I set faibit, the std exception is throws as soon as I reactiveate exceptions, again not giving me a chance to throw my own.)
Alternative 3: is it possible to set the error code that is thrown by standard exception when failbit is set ? Unfortunately, after having read about std::io_errc and std::make_error_code(), it's still not clear how I could make the failbit exception using my own error code.
Here the piece of code where error is set:
...
else if ((c = is.get()) != *p) { // input char not matching expected char
is.putback(c);
mandatory_input::read_error = c;
mandatory_input::expected = *p;
// <==== Here I would like to trigger my own exception or predefine error code thrown by standard exception
is.setstate(std::ios::failbit); // stop extracting
}
I was so concentrated on searching std functions to solve that, that I didn't think of the most obvious solution: hijacking the std exception thrown. In case it could help s.o. else:
I first defined a dedicated nested failure class:
class mandatory_input {
public:
...
class failure : public std::istream::failure {
public:
failure(std::error_code e);
};
};
Then I have added the following bloc in the original error processing code (see question):
// start of enhanced exception handling
if (is.exceptions() & std::istream::failbit) { // if exception will be thrown
try {
is.setstate(std::ios::failbit);
} catch (std::istream::failure &e) { // the failbit will trigger this
throw mandatory_input::failure(e.code()); // and i throw my own
} catch (std::exception &e) { // just in case other low-level errors would be thrown
throw e;
}
} else //======= end of enhanced exceptions handling
Now with this solution, the clients of my helper class who want to use .exceptions() can process errors either undifferentiated:
try { cin >> mandatory_input(" ( + ") >> country >> .... ;
} catch (istream::failure e) {
cerr << "Input error: "<< e.code()<< " " << e.what();
}
or fine tune error processing:
try { ....
} catch (mandatory_input::failure e) {
cerr << "Input format mismatch: " << mandatory_input::getexpected()
<< " was expected, but " << mandatory_input::getread_error() << " was read !\n";
} catch (istream::failure e) {
cerr << "Input error: "<< e.code()<< " " << e.what();
}
This code throws an exception when I enter "Timmy" as the name. I'm really not sure of the mechanism but why does it print out "abracadabra" and not "Timmy". One thing I'm sure of though is that there is no magic going on here!
This is the short code
#include <iostream>
using namespace std;
#include <string>
#include <cstdlib>
string enterName();
void checkName(string);
int main()
{
string someName = "abracadabra";
try {
someName = enterName();
}
catch(const char* error) {
cout << "main function says: "<<error <<endl;
}
cout << "Name: "<<someName<<endl;
return 0;
}
string enterName()
{
string s;
cout<<"Enter a name: ";
cin >> s;
cout<<endl;
try {
checkName(s);
}
catch(const char* err) {
cout << "middle man says: "<<err <<endl;
throw "rtetfrer";
}
return s;
}
void checkName(string name)
{
if (name == "Timmy")
throw "Help, Timmy's been kidnapped by a giant squid!";
}
You are throwing an exception, so the function never returns:
void checkName(string name)
{
if (name == "Timmy")
//This throws an exception, so the function exits immediately
throw "Help, Timmy's been kidnapped by a giant squid!";
}
That exception is caught here:
try {
checkName(s);
}
catch(const char* err) {
//This will be the exception that timmy is caught
cout << "middle man says: "<<err <<endl;
//This will throw an exception and immediately exit the function
throw "rtetfrer";
}
//This will never be called
return s;
And the new exception will be caught here:
catch(const char* error) {
cout << "main function says: "<<error <<endl;
}
But since checkName never returned a value, somename will still be magic
enterName(); throws an exception before the assignment to someName is made. Hence someName retains its original value.
(In a little more detail: enterName() calls checkName(). checkName() throws an exception since name is "Timmy". enterName() throws "rtetfrer". Why not verify with your debugger?)
In order to assign a value to someName, c++ must first evaluate the expression on the left side. That is the result of the function enterName. Now during the execution of this function an exception is thrown. When this happens the execution jumps right to the catch clause(skipping the return clause of the function and then the assignment of someName to this return value), thus you never assign a different value to someName.
Use a debugger to follow the execution flow in an easier manner.
This seems to be a trivial question but I got hung on it for a few hours now (maybe too much Java killed my C++ braincells).
I have created a class that has the following constructor (i.e. no default constructor)
VACaptureSource::VACaptureSource( std::string inputType, std::string inputLocation ) {
if( type == "" || location == "" ) {
throw std::invalid_argument("Empty type or location in VACaptureSource()");
}
type = inputType;
location = inputLocation;
// Open the given media source using the appropriate OpenCV function.
if( type.compare("image") ) {
frame = cvLoadImage( location.c_str() );
if( !frame ) {
throw std::runtime_error("error opening file");
}
}
else {
throw std::invalid_argument("Unknown input type in VACaptureSource()");
}
}
When I want to create an instance, I use
// Create input data object
try {
VACaptureSource input = VACaptureSource("image", "/home/cuneyt/workspace/testmedia/face_images/jhumpa_1.jpg");
}
catch( invalid_argument& ia ) {
cerr << "FD Error: " << ia.what() << endl;
usage(argv[0]);
}
catch( runtime_error& re ) {
cerr << "FD Error: " << re.what() << endl;
usage(argv[0]);
}
However, in this case the instance is local to this block and I can't refer to it anywhere else. On the other hand, I can't say
VACAptureSource input;
at the beginning of the program since there's no default constructor.
What is the correct way to do this?
Thanks!
why do you need to refer to it outside the try block?
Instead of
try {
VACaptureSource input = VACaptureSource("image", "/home/cuneyt/workspace/testmedia/face_images/jhumpa_1.jpg");
}
//catch....
//do stuff with input
you could move everything into the try block:
try {
VACaptureSource input = VACaptureSource("image", "/home/cuneyt/workspace/testmedia/face_images/jhumpa_1.jpg");
//do stuff with input
}
//catch....
or you could factor it out into a separate function, which is called from the try block:
void doStuff(VACaptureSource& input){
//do stuff with input
}
try {
VACaptureSource input = VACaptureSource("image", "/home/cuneyt/workspace/testmedia/face_images/jhumpa_1.jpg");
doStuff(input);
}
//catch....
The last one even gives you the nice bonus of separating the construction from use, which places nicely into unit tests where you might want the function to work on a mock object instead.
What about using a pointer (or some RAII version thereof)?
VACaptureSource* input = NULL;
try {
input = new VACaptureSource(...);
} catch(...) {
//error handling
}
//And, of course, at the end of the program
delete input;
A local variable is scoped to the block in which it's allocated (like Java) but it'll destruct as soon as the block ends (unlike Java) so you should either do all the stuff you want in the try block itself (which might not be desirable if you want to only handle constructor exceptions) or you should allocate the object somewhere else (e.g. heap) and use a pointer in the parent block to access it.
Can I just observe that just about any but the most trivial constructor can be expected to throw an exception. You should therefore not consider exceptions to be "special" in some sense, but instead write your code so that it deals with them naturally. This means using RAII, and the other techniques that other answers here have suggested.
You may use a pointer
VACaptureSource* input;
// Create input data object
try {
input = new VACaptureSource("image", "/home/cuneyt/workspace/testmedia/face_images/jhumpa_1.jpg");
}
catch( invalid_argument& ia ) {
cerr << "FD Error: " << ia.what() << endl;
usage(argv[0]);
}
catch( runtime_error& re ) {
cerr << "FD Error: " << re.what() << endl;
usage(argv[0]);
}
And you need to free the object when you finish to use it
delete input
I can't say
VACaptureSource input;
at the beginning of the program since there's no default constructor.
There is a good reason you didn't create a default constructor: namely that a VACaptureSource only makes sense when associated with a file. So don't create a default constructor. Instead simply recognize that the scope of the VACaptureSource object is the try block, and use it inside there.
What about adding a default constructor which leaves the object in a special unconfigured state? Then have an create() function for actually creating it.
Then you can do:
VACaptureSource input;
try
{
input.create("image", "...");
}
catch(...)
{
...
}
Depending on the situation this might be better than messing with pointers. Although then you also have to check if the create() was actually called before doing something...
I don't actually see any probelms here:
A couple of things I would update:
Catch exceptions by const reference.
The compiler may optimize away the copy construction in your code
But it looks neater without it. Just declare input with its parameters.
I would refactor the constructor to take const reference parameters
And I would initialise them in the initialiser list.
Also I would make sure the member 'frame' is actually a smart pointer.
So I would do this (for clarity).
VACaptureSource::VACaptureSource( std::string const& inputType,
std::string const& inputLocation )
:type(inputType)
,location(inputLocation)
{
// Other Code that throws.
}
void playWithCode()
{
// Get input information from user.
VACaptureSource input("image", "/home/cuneyt/workspace/testmedia/face_images/jhumpa_1.jpg");
// use the input object.
// Do not need to play with pointers here.
}
int main()
{
try
{
playWithCode();
}
catch( invalid_argument const& ia )
{ cerr << "FD Error: " << ia.what() << endl;
usage(argv[0]);
}
catch( runtime_error const& re )
{ cerr << "FD Error: " << re.what() << endl;
usage(argv[0]);
}
}
Simple. Don't throw exceptions within a constructor. Not only do you have to wrap the constructor in the try block, you won't be able to handle memory very well in the event you catch an exception (do you call the destructor? how much of the class's memory needs to be deleted?)
UPDATE0: Although, I'm not sure if memory management is a problem if you're using an instance.
UPDATE1: Hmmm, maybe I'm thinking about exceptions in destructors.
int
main2(int argc, char* argv[])
{
MyClass class;
class.doSomething();
}
int
main(int argc, char* argv[])
{
int result = 0;
try {
main2(argc, argv);
} catch (std::exception& se) {
// oh noes!
result = 1;
}
return result;
}