Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert errno to exception using <system_error>

I read a thoughtful series of blog posts about the new <system_error> header in C++11. It says that the header defines an error_code class that represents a specific error value returned by an operation (such as a system call). It says that the header defines a system_error class, which is an exception class (inherits from runtime_exception) and is used to wrap error_codess.

What I want to know is how to actually convert a system error from errno into a system_error so I can throw it. For example, the POSIX open function reports errors by returning -1 and setting errno, so if I want to throw an exception how should I complete the code below?

void x() {     fd = open("foo", O_RDWR);     if (fd == -1)     {         throw /* need some code here to make a std::system_error from errno */;     } } 

I randomly tried:

errno = ENOENT; throw std::system_error(); 

but the resulting exception returns no information when what() is called.

I know I could do throw errno; but I want to do it the right way, using the new <system_error> header.

There is a constructor for system_error that takes a single error_code as its argument, so if I can just convert errno to error_code then the rest should be obvious.

This seems like a really basic thing, so I don't know why I can't find a good tutorial on it.

I am using gcc 4.4.5 on an ARM processor, if that matters.

like image 366
David Grayson Avatar asked Aug 29 '12 05:08

David Grayson


People also ask

When to use assert vs exception?

Use asserts to check for errors that should never occur. Use exceptions to check for errors that might occur, for example, errors in input validation on parameters of public functions.

How to use exception handling in C++?

Exception handling in C++ consist of three keywords: try , throw and catch : The try statement allows you to define a block of code to be tested for errors while it is being executed. The throw keyword throws an exception when a problem is detected, which lets us create a custom error.

When to throw exceptions C++?

An exception should be thrown from a C++ constructor whenever an object cannot be properly constructed or initialized. Since there is no way to recover from failed object construction, an exception should be thrown in such cases.

Does C++ have exceptions?

Exception handling in C++ consists of three keywords: try, throw and catch: The try statement allows you to define a block of code to be tested for errors while it is being executed. The throw keyword throws an exception when a problem is detected, which lets us create a custom error.


2 Answers

You are on the right track, just pass the error code and a std::generic_category object to the std::system_error constructor and it should work.

Example:

#include <assert.h> #include <errno.h> #include <iostream> #include <system_error>  int main() {     try     {         throw std::system_error(EFAULT, std::generic_category());     }     catch (std::system_error& error)     {         std::cout << "Error: " << error.code() << " - " << error.what() << '\n';         assert(error.code() == std::errc::bad_address);     } } 

Output from the above program on my system is

 Error: generic:14 - Bad address 
like image 53
Some programmer dude Avatar answered Sep 17 '22 13:09

Some programmer dude


To add to the excellent accepted answer, you can enrich the error message with some contextual information in the 3rd argument, e.g. the failing file name:

std::string file_name = "bad_file_name.txt"; fd = open(file_name, O_RDWR); if (fd < 0) {     throw std::system_error(errno, std::generic_category(), file_name); } 

Then when caught, e.what() will return, for example:

bad_file_name.txt: file not found 
like image 43
rustyx Avatar answered Sep 16 '22 13:09

rustyx