472,961 Members | 1,548 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,961 software developers and data experts.

conversion: errno => exception

Do you know a class library that can convert the error/return codes
that are listed in the standard header file "errno.h" into a
well-known exception hierarchy?
Did anybody derive it from "std:runtime_error"?

Regards,
Markus
Jul 22 '05 #1
13 3818
* Markus Elfring:
Do you know a class library that can convert the error/return codes
that are listed in the standard header file "errno.h" into a
well-known exception hierarchy?
Did anybody derive it from "std:runtime_error"?


Why do you want a hierarchy?

Off the cuff:

void throwStdIoError()
{
throw std::runtime_error( std::strerror( std::errno ) );
}
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 22 '05 #2
Alf P. Steinbach wrote:
* Markus Elfring:
Do you know a class library that can convert the error/return codes
that are listed in the standard header file "errno.h" into a
well-known exception hierarchy?
Did anybody derive it from "std:runtime_error"?


Why do you want a hierarchy?

Off the cuff:

void throwStdIoError()
{
throw std::runtime_error( std::strerror( std::errno ) );
}


It would be quite hard for the function that catches the exception to find
out what the error actually is.

Jul 22 '05 #3
* Rolf Magnus:
Alf P. Steinbach wrote:
* Markus Elfring:
Do you know a class library that can convert the error/return codes
that are listed in the standard header file "errno.h" into a
well-known exception hierarchy?
Did anybody derive it from "std:runtime_error"?


Why do you want a hierarchy?

Off the cuff:

void throwStdIoError()
{
throw std::runtime_error( std::strerror( std::errno ) );
}


It would be quite hard for the function that catches the exception to find
out what the error actually is.


If it's not within the context of the throwing call, why should it care?

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 22 '05 #4
> Why do you want a hierarchy?

The reasons are similar to the design decisions for the base classes
that are specified in the header <exception> and related files.
I would like to unify error reporting and put return codes into groups
or categories. I see a problem there to find the appropriate names for
the categorization.

The application of design patterns is another use case.
- http://www.refactoring.com/catalog/r...ymorphism.html
- http://www.refactoring.com/catalog/r...WithClass.html
- http://industriallogic.com/xp/refact...WithClass.html

I imagine a factory class that provides a method like this one.
errno_exception& create(int err_no) const throw(std::out_of_range);

I suggest two approaches for its implementation.
1. a huge switch statement
2. Instances are copied from a static collection (array, vector or
map).

Have you got more ideas?
Is a complete solution available already?

Regards,
Markus
Jul 22 '05 #5
* Markus Elfring:
Why do you want a hierarchy?
The reasons are similar to the design decisions for the base classes
that are specified in the header <exception> and related files.
I would like to unify error reporting and put return codes into groups
or categories. I see a problem there to find the appropriate names for
the categorization.


If naming is a problem, then the idea is probably not meaningful.

The base classes in <exception> are meant to facilitate different handling
of different kinds of error state, primarily to diffentiate between
recoverable/ignorable on the one hand, and unrecoverable/non-ignorable.

But <exception> is very badly designed (if it is designed at all ;-)).
It probably emerged as a "let's get it over with, choose something!" solution
to a lot of confusion and disagreement. And so for many years Microsoft's
documentation incorrectly referred to a completely different hierarchy...

The application of design patterns is another use case.
- http://www.refactoring.com/catalog/r...ymorphism.html
- http://www.refactoring.com/catalog/r...WithClass.html
- http://industriallogic.com/xp/refact...WithClass.html
Regarding "replaceTypeCodeWithClass", consider how much easier it is to
"replace type code with log message", which is all you ordinarily need.

Do not be blinded by design patterns.

A list of design patterns can be a good source of ideas, but forcing a
pattern on a design is usually UnGood: instead, see what pattern is there
in the first place.

I imagine a factory class that provides a method like this one.
errno_exception& create(int err_no) const throw(std::out_of_range);


Regarding C++ the result should be const, and it's not a good idea to use
std::out_of_range (I haven't checked that the name is correct): instead,
use std::runtime_error or derived classes for recoverable errors, so that
other code won't get an exception it doesn't expect and won't have to
check for a zillion silly different types of exception.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 22 '05 #6
Alf P. Steinbach wrote:
* Rolf Magnus:
Alf P. Steinbach wrote:
> * Markus Elfring:
>> Do you know a class library that can convert the error/return codes
>> that are listed in the standard header file "errno.h" into a
>> well-known exception hierarchy?
>> Did anybody derive it from "std:runtime_error"?
>
> Why do you want a hierarchy?
>
> Off the cuff:
>
> void throwStdIoError()
> {
> throw std::runtime_error( std::strerror( std::errno ) );
> }


It would be quite hard for the function that catches the exception to
find out what the error actually is.


If it's not within the context of the throwing call, why should it care?


If it doesn't care, what's the purpose of the exception?
Jul 22 '05 #7
* Rolf Magnus:
Alf P. Steinbach wrote:
* Rolf Magnus:
Alf P. Steinbach wrote:

> * Markus Elfring:
>> Do you know a class library that can convert the error/return codes
>> that are listed in the standard header file "errno.h" into a
>> well-known exception hierarchy?
>> Did anybody derive it from "std:runtime_error"?
>
> Why do you want a hierarchy?
>
> Off the cuff:
>
> void throwStdIoError()
> {
> throw std::runtime_error( std::strerror( std::errno ) );
> }

It would be quite hard for the function that catches the exception to
find out what the error actually is.


If it's not within the context of the throwing call, why should it care?


If it doesn't care, what's the purpose of the exception?


Most actual code does not use information about the type of a caught
exception.

The only relevant information is, usually, that an exception occurred, and
(for purposes of logging) the explanatory string carried by the exception.

Hence your question is really "why does C++ support exceptions", and that
belongs in [comp.std.c++], or a programming textbook, if anywhere.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 22 '05 #8
On 8 Nov 2004 10:59:11 -0800, Ma************@web.de (Markus Elfring)
wrote:
Why do you want a hierarchy?
The reasons are similar to the design decisions for the base classes
that are specified in the header <exception> and related files.
I would like to unify error reporting and put return codes into groups
or categories. I see a problem there to find the appropriate names for
the categorization.

The application of design patterns is another use case.
- http://www.refactoring.com/catalog/r...ymorphism.html
- http://www.refactoring.com/catalog/r...WithClass.html
- http://industriallogic.com/xp/refact...WithClass.html

I imagine a factory class that provides a method like this one.
errno_exception& create(int err_no) const throw(std::out_of_range);


That isn't going to work, since if you do:

throw create(errno);

the exception object will be sliced, since in C++ the static type of a
throw statement determines the type of exception thrown. This of
course assumes that you are going to add classes derived from
errno_exception.
I suggest two approaches for its implementation.
1. a huge switch statement
2. Instances are copied from a static collection (array, vector or
map).

Have you got more ideas?
You could use a map from error number to a throw function. e.g.

template <class Exception> void thrower(int errorCode/*other
params?*/)
{
throw Exception(errorCode/*other params?*/);
}

and a map:

std::map<int, void(int)> throwers;

Insert in the map with:

throwers[someErrorCode] = &thrower<SomeExceptionClass>;

Then you throw with:

void throwErrNo(int errorNumber/*other params?*/)
{
iterator i = throwers.find(someErrorCode);
if (i != throwers.end())
{
(i->second)(someErrorCode/*other params?*/);
}
else
{
//either throw errno_exception or out_of_range
//or even assert?
}
}

If the sequence of error numbers is fairly contiguous, you could use a
vector rather than a map. Alternatively, you could just use the switch
statement - this depends on whether you want the thing to be runtime
pluggable with new error codes, etc.
Is a complete solution available already?


Not that I know of.

Tom
Jul 22 '05 #9
* Tom Widmer:
* Markus Elfring:

I imagine a factory class that provides a method like this one.
errno_exception& create(int err_no) const throw(std::out_of_range);


That isn't going to work, since if you do:

throw create(errno);

the exception object will be sliced, since in C++ the static type of a
throw statement determines the type of exception thrown. This of
course assumes that you are going to add classes derived from
errno_exception.


Well, what you describe here wasn't mentioned by Markus.

Hence the "that" that isn't going to work is your code... ;-)

Because of that the natural assumption is that his errno_exception is a
factory, or that it directly provides a virtual throw function.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 22 '05 #10
On Tue, 09 Nov 2004 22:29:24 GMT, al***@start.no (Alf P. Steinbach)
wrote:
* Tom Widmer:
* Markus Elfring:
>
>I imagine a factory class that provides a method like this one.
> errno_exception& create(int err_no) const throw(std::out_of_range);


That isn't going to work, since if you do:

throw create(errno);

the exception object will be sliced, since in C++ the static type of a
throw statement determines the type of exception thrown. This of
course assumes that you are going to add classes derived from
errno_exception.


Well, what you describe here wasn't mentioned by Markus.

Hence the "that" that isn't going to work is your code... ;-)

Because of that the natural assumption is that his errno_exception is a
factory, or that it directly provides a virtual throw function.


True, but I thought it was worth highlighting the issue just in case
he wasn't aware of it.

Actually, a virtual throw method is generally a good idea in any
exception heirarchy, along with a clone method, so that you can
propogate exceptions between threads, etc.

Tom
Jul 22 '05 #11
> That isn't going to work, since if you do:

How do you think about an interface like this one?
virtual errno_exception& create(int err_no) const;

throw create(errno);
I would like to use ...
throw my_exception_factory.create(errno);

the exception object will be sliced, since in C++ the static type of a
throw statement determines the type of exception thrown. This of
course assumes that you are going to add classes derived from
errno_exception.


I do not think that "object slicing" will happen.
http://www.savinov.spb.ru/think/tic0161.html#Heading428

How does your statement fit to the handling of "covariant return types"?
http://www.fmi.uni-konstanz.de/~kueh....html#faq-20.6
http://www.fmi.uni-konstanz.de/~kueh....html#faq-22.5
http://semantics.org/once_weakly/ck1...iantreturn.pdf
Jul 22 '05 #12
On 12 Nov 2004 03:14:26 -0800, Ma************@web.de (Markus Elfring)
wrote:
That isn't going to work, since if you do:
How do you think about an interface like this one?
virtual errno_exception& create(int err_no) const;

throw create(errno);


I would like to use ...
throw my_exception_factory.create(errno);


That's exactly what won't work. You will need something like:

my_exception_factory.create(errno).throw_self();

where throw_self is a virtual function that is implemented in every
exception class that simply does throw *this;
Or you can have:

my_exception_factory.throw_error(errno);

or similar.
the exception object will be sliced, since in C++ the static type of a
throw statement determines the type of exception thrown. This of
course assumes that you are going to add classes derived from
errno_exception.


I do not think that "object slicing" will happen.
http://www.savinov.spb.ru/think/tic0161.html#Heading428


Throwing an exception involves copying it. In the statement "throw t"
the static type of t is used to determine the exception that is
thrown. t is copied into a "temporary" exception object of type
static-type-of-t, and this copy will be a slice if the static type of
t doesn't match its dynamic type.
How does your statement fit to the handling of "covariant return types"?
http://www.fmi.uni-konstanz.de/~kueh....html#faq-20.6
http://www.fmi.uni-konstanz.de/~kueh....html#faq-22.5
http://semantics.org/once_weakly/ck1...iantreturn.pdf


I don't think that covariant returns will make any difference here.

Tom
Jul 22 '05 #13
> Throwing an exception involves copying it. In the statement "throw t"
the static type of t is used to determine the exception that is
thrown. t is copied into a "temporary" exception object of type
static-type-of-t, and this copy will be a slice if the static type of
t doesn't match its dynamic type.


How do you think about the effects by the following design sketch?

#include <iostream.h>
#include <errno.h>

struct errno_exception
{
virtual ~errno_exception() {}
virtual int get_code() const { return EZERO; }
};
struct invalid : public errno_exception
{
};
struct invalid_value : public invalid
{
virtual int get_code() const { return EINVAL; }
};
struct invalid_environment : public invalid
{
virtual int get_code() const { return EINVENV; }
};
struct invalid_format : public invalid
{
virtual int get_code() const { return EINVFMT; }
};
struct no_entry : public errno_exception
{
virtual int get_code() const { return ENOENT; }
};
struct exception_factory
{
virtual ~exception_factory() {}
virtual errno_exception& create (int err_no) const = 0;
};
struct factory1 : public exception_factory
{
virtual errno_exception& create (int err_no) const;
};
struct errno_exceptions
{
errno_exception _ZERO;
no_entry _NOENT;
invalid_format _INVFMT;
invalid_environment _INVENV;
invalid_value _INVAL;
};
errno_exceptions my_e_e;
errno_exception& factory1::create (int err_no) const
{
switch (err_no)
{
case ENOENT:
return my_e_e._NOENT;

case EINVFMT:
return my_e_e._INVFMT;

case EINVENV:
return my_e_e._INVENV;

case EINVAL:
return my_e_e._INVAL;

default:
return my_e_e._ZERO;
}
}
struct exception_thrower
{
virtual ~exception_thrower() {}
virtual void create (int code) const = 0;
};
struct factory2 : public exception_thrower
{
virtual void create (int code) const;
};
void factory2::create (int code) const
{
switch (code)
{
case ENOENT:
throw no_entry();

case EINVFMT:
throw invalid_format();

case EINVENV:
throw invalid_environment();

case EINVAL:
throw invalid_value();

default:
throw errno_exception();
}
}
int main ()
{
factory1 f1;

try
{
throw f1.create(EINVFMT);
}
catch (invalid const& i)
{
cout << "1. invalid = " << i.get_code() << endl;
}
catch (errno_exception const& e)
{
cout << "1. errno exception base" << endl;
}

try
{
factory2 f2;
f2.create(EINVFMT);
}
catch (invalid const& i)
{
cout << "2. invalid = " << i.get_code() << endl;
}
catch (errno_exception const& e)
{
cout << "2. errno exception base" << endl;
}

return 0;
}

Jul 22 '05 #14

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Mark Harrison | last post by:
Can somebody loan me a clue as to how to check the errno on an OSError, as described below? try: os.makedirs(d) except OSError: # if errno == 17 then silently ignore the error because the #...
0
by: nicogrubert | last post by:
Hi there I am trying to read the content of a really large text file (1GByte) and I get the following exception if I try to call readlines() on the opened textfile: IOError: Cannot allocate...
3
by: Scott Whitney | last post by:
oldName=/backup/backups/data/WWW_httpd.conf_backups/20050204.httpd.conf newName=/backup_old/data/WWW_httpd.conf_backups/20050204.httpd.conf os.rename(oldName,newName) gives: OSError: ...
4
by: Jim Hubbard | last post by:
I have some C# code that is supposed to wrap the defrag APIs and I am trying to convert it to VB.Net (2003). But, I keep having problems. The C# code is relatively short, so I'll post it...
3
by: Siemel Naran | last post by:
Here is a question about implicit conversion from T (&) to ptrcarray<T>. I wrote a class template <class T> struct ptrcarray { T * array; size_t size;
11
by: Aaron Queenan | last post by:
Given the classes: class Class { public static implicit operator int(Class c) { return 0; } } class Holder
5
by: Urs Beeli | last post by:
I have a question regarding errno. If I understand it correctly, including <errno.h> allows me to check "errno" for error values that some standard library functions may set. This brings up some...
28
by: James Brown | last post by:
All, I have a series of characters which I need to convert to integer values. Each character is read in turn from a function 'nextch', and hex-digits are identified by the isxdigit function - so...
15
by: bcpkh | last post by:
Hello All I have a simple task that is driving me crazy. A string representing a duration in the following format is passed to my application, a function is dedicated to convert this duration to...
2
by: DJRhino | last post by:
Was curious if anyone else was having this same issue or not.... I was just Up/Down graded to windows 11 and now my access combo boxes are not acting right. With win 10 I could start typing...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 4 Oct 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
0
by: Aliciasmith | last post by:
In an age dominated by smartphones, having a mobile app for your business is no longer an option; it's a necessity. Whether you're a startup or an established enterprise, finding the right mobile app...
2
by: giovanniandrean | last post by:
The energy model is structured as follows and uses excel sheets to give input data: 1-Utility.py contains all the functions needed to calculate the variables and other minor things (mentions...
3
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be using a very simple database which has Form (clsForm) & Report (clsReport) classes that simply handle making the calling Form invisible until the Form, or all...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 1 Nov 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM) Please note that the UK and Europe revert to winter time on...
0
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be focusing on the Report (clsReport) class. This simply handles making the calling Form invisible until all of the Reports opened by it have been closed, when it...
0
isladogs
by: isladogs | last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, Mike...
2
by: GKJR | last post by:
Does anyone have a recommendation to build a standalone application to replace an Access database? I have my bookkeeping software I developed in Access that I would like to make available to other...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.