A matter of exception reporting style

Discussion in 'C++' started by mzdude, Aug 12, 2009.

  1. mzdude

    mzdude Guest

    During a code review the other day I noticed we have some
    code that could be refactored.

    Err.h

    struct Error {
    int errCode;
    std::wstring reason;

    Error(int e, wchar_t const *r )
    : errCode(e)
    , reason(r)
    {}

    };

    const int ErrCode1 = 1000;
    const int Errcode2 = 1001;
    ....


    File1.cpp
    void SomeFunct() {
    if(cond)
    throw Error( ErrCode1, L"This is an error");
    }


    File2.cpp
    void AnotherFunc() {
    if(cond)
    throw Error( ErrCode1, L"This is an Error.");
    }

    Note the slight discrepancy in the error strings.
    Obviously refactoring is the key to consistency.
    But how to refactor?

    In Err.h

    // option 1, function returns object
    Error Error_Code1()
    { return Error(ErrCode1, L"This is an error"); }

    // option 2, single definition of a static object
    // in this case all ErrCodeX's go away
    extern Error Error_Code1;

    // option 3, function actually does the throw
    void ThrowError_Code1()
    { throw Error(ErrCode1, L"This is an error"); }


    void SomeFunct() {
    if(cond)
    throw Error_Code1();

    if(cond)
    throw Error_Code1;

    if(cond)
    ThrowError_Code1();

    My current preference is leaning towards option 1 for
    several reason. No time wasted in constructing lots
    of exceptions at start up time (as compared to option 2).
    Option 3 hides what is happening when tracing through
    the higher level code. It is only the function name that
    makes it obvious.

    In the future, this code **may** get internationalized,
    in which case the string would move to a resource file.
    mzdude, Aug 12, 2009
    #1
    1. Advertising

  2. * mzdude:
    > During a code review the other day I noticed we have some
    > code that could be refactored.
    >
    > Err.h
    >
    > struct Error {
    > int errCode;
    > std::wstring reason;
    >
    > Error(int e, wchar_t const *r )
    > : errCode(e)
    > , reason(r)
    > {}
    >
    > };


    Should derive from std::runtime_error.

    When you do introduce your own exception class it's also a Good Idea to add a
    virtual rethrow() routine.

    That way exceptions can more easily be propagated across C code, e.g. from
    callbacks.


    > const int ErrCode1 = 1000;
    > const int Errcode2 = 1001;
    > ...
    >
    >
    > File1.cpp
    > void SomeFunct() {
    > if(cond)
    > throw Error( ErrCode1, L"This is an error");
    > }
    >
    >
    > File2.cpp
    > void AnotherFunc() {
    > if(cond)
    > throw Error( ErrCode1, L"This is an Error.");
    > }
    >
    > Note the slight discrepancy in the error strings.
    > Obviously refactoring is the key to consistency.
    > But how to refactor?


    Introduce a mapping from error codes to strings.

    Take care not to make that error code/string the primary message (as it seems to
    be above), but just a convenience add-on.

    For in order to avoid an administrative and maintainance nightmare you
    absolutely don't want to force all exception usage to use predefined strings.


    Cheers & hth.,

    - Alf
    Alf P. Steinbach, Aug 12, 2009
    #2
    1. Advertising

  3. mzdude <> writes:

    > During a code review the other day I noticed we have some
    > code that could be refactored.
    >
    > Err.h
    >
    > struct Error {
    > int errCode;
    > std::wstring reason;
    >
    > Error(int e, wchar_t const *r )
    > : errCode(e)
    > , reason(r)
    > {}
    >
    > };
    >
    > const int ErrCode1 = 1000;
    > const int Errcode2 = 1001;
    > ...
    >
    >
    > File1.cpp
    > void SomeFunct() {
    > if(cond1)
    > throw Error( ErrCode1, L"This is an error");


    throw Error( ErrCode1, std::wstring("The reason why there is an ErrCode1 is because <cond1>."));

    > }
    >
    >
    > File2.cpp
    > void AnotherFunc() {
    > if(cond2)
    > throw Error( ErrCode1, L"This is an Error.");


    throw Error( ErrCode1, std::wstring(/*This time, */"The reason why there is an ErrCode1 is because <cond2>."));

    > }
    >
    > Note the slight discrepancy in the error strings.


    ISTM that the problem is not the slight discrepancy in the strings,
    but their close ressemblance, assuming the two conditions that raised
    the error ErrCode1 are different!

    > Obviously refactoring is the key to consistency.
    > But how to refactor?


    Actually, one problem is in the use of enums.

    I understand that for external references it might be useful to have
    error codes, and that small integers might be practical for such error
    codes. But internally, you shouldn't have to deal with them.

    class ErrorConditionOne: public Error { ErrorConditionOne():errCode(1001){}; };
    class ErrorConditionTwo: public Error { ErrorConditionOne():errCode(1002){}; };

    You might want to document here the meaning of ErrorConditionOne, etc,
    so you can build the user documentation error-code annex
    automatically:

    class ErrorConditionOne: public Error { ErrorConditionOne():errCode(1001),errExplain("<Condition One Occured>"){}; };
    class ErrorConditionTwo: public Error { ErrorConditionOne():errCode(1002),errExplain("<Condition Two Occured>"){}; };

    But this text has nothing to do with the actual reason why condition one occured...

    void funA()
    if(conditionOne){
    throw ErrorConditionOne("When doing <funA stuff> we expected not <conditionOne>.");
    }
    }

    void funB()
    if(conditionTwo){
    throw ErrorConditionTwo("When doing <funB stuff> we expected not <conditionTwo>.");
    }
    }


    > In the future, this code **may** get internationalized,
    > in which case the string would move to a resource file.


    In any case, almost all strings are to be internationalized. This is an orthogonal problem.

    --
    __Pascal Bourguignon__
    Pascal J. Bourguignon, Aug 12, 2009
    #3
  4. mzdude

    mzdude Guest

    On Aug 12, 9:23 am, "Alf P. Steinbach" <> wrote:
    > Should derive from std::runtime_error.

    Why?? We don't use narrow char unless forced to for historical
    interface reasons.

    >
    > When you do introduce your own exception class it's also a Good Idea to add a
    > virtual rethrow() routine.
    >
    > That way exceptions can more easily be propagated across C code, e.g. from
    > callbacks.

    Not sure what you mean by this.

    >
    > > const int ErrCode1 = 1000;
    > > const int Errcode2 = 1001;
    > > ...

    >
    > > File1.cpp
    > > void SomeFunct() {
    > >     if(cond)
    > >        throw Error( ErrCode1, L"This is an error");
    > > }

    >
    > > File2.cpp
    > > void AnotherFunc() {
    > >   if(cond)
    > >     throw Error( ErrCode1, L"This is an Error.");
    > > }

    >
    > > Note the slight discrepancy in the error strings.
    > > Obviously refactoring is the key to consistency.
    > > But how to refactor?

    >
    > Introduce a mapping from error codes to strings.
    >
    > Take care not to make that error code/string the primary message (as it seems to
    > be above), but just a convenience add-on.


    That is the case. The error code is the important. The message is for
    the human (maybe).
    mzdude, Aug 12, 2009
    #4
  5. mzdude

    mzdude Guest

    On Aug 12, 10:01 am, (Pascal J. Bourguignon)
    wrote:
    >
    > ISTM that the problem  is not the slight discrepancy in the strings,
    > but their close ressemblance, assuming the two conditions that raised
    > the error ErrCode1 are different!
    >

    No actually the conditions are identical.
    >
    > Actually, one problem is in the use of enums.

    I don't see it that way.
    >
    > I understand that for external references it might be useful to have
    > error codes, and that small integers might be practical for such error
    > codes.  But internally, you shouldn't have to deal with them.
    >

    This particular mechanism is for a progromatic interface. Through a
    published API a calling program has violated the contract. We are
    returning the results. In this case the results will be formulated
    into XML (not that it's terribly relevant).
    <Result Status="Fail" ErrId="100">Reason for failure goes here</
    Result>

    The calling program can take corrective measures based on the
    error code more easily than it can for text.
    mzdude, Aug 12, 2009
    #5
  6. * mzdude:
    > On Aug 12, 9:23 am, "Alf P. Steinbach" <> wrote:
    >> Should derive from std::runtime_error.

    > Why??


    Multiple exclamation marks, ... :) (I'm sure you can look up that quote)

    Anyways, you want to base your exceptions on std::exception in order to support
    code that deals with and expects std::exception, and then std::runtime_error is
    the logical general choice of standard exception base class.

    There's nothing more annoying than using libraries that throw non-standard
    exceptions, necessitating exception conversion or big multiple catches in the
    calling code.


    > We don't use narrow char unless forced to for historical
    > interface reasons.


    For exceptions you should.

    There is AFAIK no reason to support wide characters in exceptions.

    The same internal failure can cause different user level failures; different
    internal failures can cause the same user level failure; and the requirements on
    information conveyed, internationalization etc. are vastly different.

    So user interface messages should ideally not be carried by exceptions.

    And so in a non-trivial app it's a good idea to separate exceptions (internal
    failure reporting) from the user interface aspect (user failure reporting).



    >> When you do introduce your own exception class it's also a Good Idea to add a
    >> virtual rethrow() routine.
    >>
    >> That way exceptions can more easily be propagated across C code, e.g. from
    >> callbacks.

    > Not sure what you mean by this.


    It means that before returning to C code that was called by your code, you can
    dynamically copy the exception somewhere (for complete generality it helps if it
    supports cloning), and on return from C code you can rethrow the exception with
    original type.

    For the C code in between may not support exception propagation.


    >>> const int ErrCode1 = 1000;
    >>> const int Errcode2 = 1001;
    >>> ...
    >>> File1.cpp
    >>> void SomeFunct() {
    >>> if(cond)
    >>> throw Error( ErrCode1, L"This is an error");
    >>> }
    >>> File2.cpp
    >>> void AnotherFunc() {
    >>> if(cond)
    >>> throw Error( ErrCode1, L"This is an Error.");
    >>> }
    >>> Note the slight discrepancy in the error strings.
    >>> Obviously refactoring is the key to consistency.
    >>> But how to refactor?

    >> Introduce a mapping from error codes to strings.
    >>
    >> Take care not to make that error code/string the primary message (as it seems to
    >> be above), but just a convenience add-on.

    >
    > That is the case. The error code is the important. The message is for
    > the human (maybe).


    If you make the error code the important, then you're most probably heading for
    the nightmare I mentioned.

    At the worst you'll end up with a repository/database of error codes and
    strings, a set of small utilities for handling that, a person in charge of that,
    and umpteen man-months wasted searching for proper error codes or creating them.

    Generally all that matters for code that handles an exception is that there was
    an exception, and all that matters for someone inspecting a log is the textual
    message and throw context. I use exceptions that can carry a Windows error code.
    However, even when an exception is caused by an API failure there isn't
    necessarily a reasonable error code available, or the error code can be so
    generic as to not say anything really (e.g. E_FAIL), and it doesn't say which
    API routine failed, nor which of my routines failed. So the important thing for
    debugging, logging and so on is the text, supplied by the throwing code.


    Cheers & hth.,

    - Alf
    Alf P. Steinbach, Aug 12, 2009
    #6
  7. * mzdude:
    > On Aug 12, 10:01 am, (Pascal J. Bourguignon)
    > wrote:
    >> ISTM that the problem is not the slight discrepancy in the strings,
    >> but their close ressemblance, assuming the two conditions that raised
    >> the error ErrCode1 are different!
    >>

    > No actually the conditions are identical.
    >> Actually, one problem is in the use of enums.

    > I don't see it that way.
    >> I understand that for external references it might be useful to have
    >> error codes, and that small integers might be practical for such error
    >> codes. But internally, you shouldn't have to deal with them.
    >>

    > This particular mechanism is for a progromatic interface. Through a
    > published API a calling program has violated the contract. We are
    > returning the results. In this case the results will be formulated
    > into XML (not that it's terribly relevant).
    > <Result Status="Fail" ErrId="100">Reason for failure goes here</
    > Result>
    >
    > The calling program can take corrective measures based on the
    > error code more easily than it can for text.


    It can even more easily distinguish exception types. ;-)


    Cheers & hth.,

    - Alf
    Alf P. Steinbach, Aug 12, 2009
    #7
  8. Alf P. Steinbach schrieb:
    >> This particular mechanism is for a progromatic interface. Through a
    >> published API a calling program has violated the contract. We are
    >> returning the results. In this case the results will be formulated
    >> into XML (not that it's terribly relevant).
    >> <Result Status="Fail" ErrId="100">Reason for failure goes here</
    >> Result>
    >>
    >> The calling program can take corrective measures based on the
    >> error code more easily than it can for text.

    >
    > It can even more easily distinguish exception types. ;-)


    How to get the type of exception into XML form? For external programs,
    C++ classes don't have any meaning.

    But instead of the (magic) numeric constant, the XML could contain an
    error code string like ErrId="ErrCode1".

    --
    Thomas
    Thomas J. Gritzan, Aug 12, 2009
    #8
  9. * Thomas J. Gritzan:
    > Alf P. Steinbach schrieb:
    >>> This particular mechanism is for a progromatic interface. Through a
    >>> published API a calling program has violated the contract. We are
    >>> returning the results. In this case the results will be formulated
    >>> into XML (not that it's terribly relevant).
    >>> <Result Status="Fail" ErrId="100">Reason for failure goes here</
    >>> Result>
    >>>
    >>> The calling program can take corrective measures based on the
    >>> error code more easily than it can for text.

    >> It can even more easily distinguish exception types. ;-)

    >
    > How to get the type of exception into XML form?


    That depends on the usage context. E.g. for XML as the serialization form of
    remote procedure calls one would presumably need to conform to that. But the
    basics is not more difficult than the base exception class providing a virtual
    routine that supplies the class identifier.


    > For external programs,
    > C++ classes don't have any meaning.


    The OP's original problem description used examples with 'throw ...', and the
    new details supplied above still talk about a calling program.

    There was no XML conversion.

    A problem about exception class design is not a problem of XML conversion.


    > But instead of the (magic) numeric constant, the XML could contain an
    > error code string like ErrId="ErrCode1".


    Yeah.


    Cheers,

    - Alf
    Alf P. Steinbach, Aug 12, 2009
    #9
  10. mzdude

    mzdude Guest

    On Aug 12, 11:47 am, "Alf P. Steinbach" <> wrote:
    > * mzdude:
    >
    > > The calling program can take corrective measures based on the
    > > error code more easily than it can for text.

    >
    > It can even more easily distinguish exception types. ;-)
    >



    Not when the calling program can be written in any language.
    They may not even have types. :^)

    The exception is caught by my interface logic. It is then
    converted to the proper format and marshalled as string
    data between the two processes.
    mzdude, Aug 12, 2009
    #10
  11. mzdude

    mzdude Guest

    On Aug 12, 12:17 pm, "Thomas J. Gritzan" <>
    wrote:
    > But instead of the (magic) numeric constant, the XML could contain an
    > error code string like ErrId="ErrCode1".
    >

    But then you're back to making the calling program work with strings.
    Where they are trying to figure out why "errcode1" != "ErrCode1" !=
    "Errcode1" ...
    but 1000 always equals 1000 when converted to an integral value.
    mzdude, Aug 12, 2009
    #11
  12. mzdude

    mzdude Guest

    Rather than have this thread degenerate into
    a philosophical debate on exceptions, I'll just
    go with option 1.

    BTW, I'd love to participate in a general discussion
    on the appropriate handling of exceptions.

    // option 1, function returns object
    Error Error_Code1()
    { return Error(ErrCode1, L"This is an error"); }

    Unless someone has convincing arguements not to.
    mzdude, Aug 12, 2009
    #12
  13. mzdude schrieb:
    > On Aug 12, 12:17 pm, "Thomas J. Gritzan" <>
    > wrote:
    >> But instead of the (magic) numeric constant, the XML could contain an
    >> error code string like ErrId="ErrCode1".
    >>

    > But then you're back to making the calling program work with strings.
    > Where they are trying to figure out why "errcode1" != "ErrCode1" !=
    > "Errcode1" ...
    > but 1000 always equals 1000 when converted to an integral value.


    In your example:

    <Result Status="Fail" ErrId="100">

    Is Result always Result or can it also be RESULT? Can you write <result
    status="FAIL" errid="100">? If the XML is case-insensitive, the data can
    be, too.

    A string like "ERROR_NO_MEMORY" or "FILE_NOT_FOUND" is more meaningful
    than a number like 47 or 80.

    --
    Thomas
    Thomas J. Gritzan, Aug 12, 2009
    #13
  14. mzdude schrieb:
    > Rather than have this thread degenerate into
    > a philosophical debate on exceptions, I'll just
    > go with option 1.
    >
    > BTW, I'd love to participate in a general discussion
    > on the appropriate handling of exceptions.
    >
    > // option 1, function returns object
    > Error Error_Code1()
    > { return Error(ErrCode1, L"This is an error"); }
    >
    > Unless someone has convincing arguements not to.


    How about a ErrorCode to string map?

    void throw_Error(int ErrorCode)
    {
    throw Error(ErrorCode, getErrorDescription(ErrorCode));
    }

    Start with a std::map or std::binary_search over a list of
    ErrorCode<=>Description mappings.

    That's easily extensible to locale dependent lookup.

    --
    Thomas
    Thomas J. Gritzan, Aug 12, 2009
    #14
  15. mzdude

    mzdude Guest

    On Aug 12, 1:10 pm, "Thomas J. Gritzan" <>
    wrote:
    > mzdude schrieb:
    >
    > > On Aug 12, 12:17 pm, "Thomas J. Gritzan" <>
    > > wrote:
    > >> But instead of the (magic) numeric constant, the XML could contain an
    > >> error code string like ErrId="ErrCode1".

    >
    > > But then you're back to making the calling program work with strings.
    > > Where they are trying to figure out why "errcode1" != "ErrCode1" !=
    > > "Errcode1" ...
    > > but 1000 always equals 1000 when converted to an integral value.

    >
    > In your example:
    >
    > <Result Status="Fail" ErrId="100">
    >
    > Is Result always Result or can it also be RESULT? Can you write <result
    > status="FAIL" errid="100">? If the XML is case-insensitive, the data can
    > be, too.

    Point taken.

    > A string like "ERROR_NO_MEMORY" or "FILE_NOT_FOUND" is more meaningful
    > than a number like 47 or 80.
    >

    Only for humans.
    <Result Status="Fail" ErrId="100">File (c:\asdf\as.dat) not found</
    Result>
    is a way better message though.

    And I don't even want to discuss the use of "_" vs " " (space).
    ErrId="File Not Found"
    mzdude, Aug 12, 2009
    #15
  16. mzdude

    mzdude Guest

    On Aug 12, 1:17 pm, "Thomas J. Gritzan" <>
    wrote:
    > How about a ErrorCode to string map?
    >
    > void throw_Error(int ErrorCode)
    > {
    >    throw Error(ErrorCode, getErrorDescription(ErrorCode));
    >
    > }
    >
    > Start with a std::map or std::binary_search over a list of
    > ErrorCode<=>Description mappings.
    >
    > That's easily extensible to locale dependent lookup.


    So you think calling the function that specifically
    throws is the better option.

    As to the mechanism of the map, that falls under
    the auspices of constructing everything at once.
    To be done ither at start up or as a singleton.
    mzdude, Aug 12, 2009
    #16
  17. mzdude

    James Kanze Guest

    On Aug 12, 3:23 pm, "Alf P. Steinbach" <> wrote:
    > * mzdude:


    [...]
    > When you do introduce your own exception class it's also a
    > Good Idea to add a virtual rethrow() routine.


    The standard name for this function is raise, and it should be
    virtual, in the base class. That way, the function that
    ultimately throws the exception doesn't have to worry about
    handling every different type. (It should be present and
    virtual, in std::exception, but it isn't.)

    [...]
    > Introduce a mapping from error codes to strings.


    The real problem is that most strings reporting errors aren't
    fixed---they include things like filenames, user names, etc.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Aug 13, 2009
    #17
  18. mzdude

    James Kanze Guest

    On Aug 12, 5:46 pm, "Alf P. Steinbach" <> wrote:
    > * mzdude:


    > > On Aug 12, 9:23 am, "Alf P. Steinbach" <> wrote:
    > >> Should derive from std::runtime_error.


    [...]
    > > We don't use narrow char unless forced to for historical
    > > interface reasons.


    > For exceptions you should.


    > There is AFAIK no reason to support wide characters in
    > exceptions.


    It depends...

    > The same internal failure can cause different user level
    > failures; different internal failures can cause the same user
    > level failure; and the requirements on information conveyed,
    > internationalization etc. are vastly different.


    > So user interface messages should ideally not be carried by
    > exceptions.


    Totally agreed, but the exception must carry all necessary
    information, which might include things like the user name, a
    filename, the actual data base request which failed, why the
    request failed, etc. And some of these might only be available
    as wide character strings. (I've not encountered the problem
    myself, since I tend to use UTF-8 for all of my text. But it's
    certainly a potential problem, especially under Windows, where
    filenames, etc. may be wchar_t strings.)

    > >> That way exceptions can more easily be propagated across C
    > >> code, e.g. from callbacks.

    > > Not sure what you mean by this.


    > It means that before returning to C code that was called by
    > your code, you can dynamically copy the exception somewhere
    > (for complete generality it helps if it supports cloning), and
    > on return from C code you can rethrow the exception with
    > original type.


    Just a reminder as well---threading almost always involves C
    interfaces at the lowest levels; you'll need to clone and
    rethrow the exception if you want to propagate it over a join,
    for example.

    > For the C code in between may not support exception
    > propagation.


    In the case of join, it almost certainly doesn't, since
    exception propagation involves stack unwinding, and you're
    moving from one stack to another.

    > >> Take care not to make that error code/string the primary
    > >> message (as it seems to be above), but just a convenience
    > >> add-on.


    > > That is the case. The error code is the important. The
    > > message is for the human (maybe).


    > If you make the error code the important, then you're most
    > probably heading for the nightmare I mentioned.


    > At the worst you'll end up with a repository/database of error
    > codes and strings, a set of small utilities for handling that,
    > a person in charge of that, and umpteen man-months wasted
    > searching for proper error codes or creating them.


    Yep. That's life. It is, regretfully, something you can't
    really avoid. (But correctly managed, it's not very expensive.)

    > Generally all that matters for code that handles an exception
    > is that there was an exception,


    Generally isn't always. If a transaction fails because of some
    erroneous information the user entered, it's very useful to be
    able to point out to him what that information was. When a
    server returns an error, it should return a maximum of
    information, so that when the GUI client receives the error, it
    can e.g. highlight the erroneous fields in the input form,
    perhaps even indicating precisely what was wrong with them.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Aug 13, 2009
    #18
  19. mzdude

    James Kanze Guest

    On Aug 12, 5:11 pm, mzdude <> wrote:
    > On Aug 12, 10:01 am, (Pascal J. Bourguignon)
    > wrote:


    > > ISTM that the problem is not the slight discrepancy in the
    > > strings, but their close ressemblance, assuming the two
    > > conditions that raised the error ErrCode1 are different!


    > No actually the conditions are identical.


    > > Actually, one problem is in the use of enums.


    > I don't see it that way.


    > > I understand that for external references it might be useful
    > > to have error codes, and that small integers might be
    > > practical for such error codes. But internally, you
    > > shouldn't have to deal with them.


    > This particular mechanism is for a progromatic interface.
    > Through a published API a calling program has violated the
    > contract. We are returning the results. In this case the
    > results will be formulated into XML (not that it's terribly
    > relevant).
    > <Result Status="Fail" ErrId="100">Reason for failure goes here</
    > Result>


    > The calling program can take corrective measures based on the
    > error code more easily than it can for text.


    If the calling code is likely to want to distinguish between
    types of errors, you probably need to make different types of
    errors different derived types, so the distinction can be made
    directly in the catch.

    If the error is going to be propagated, and handled by a program
    at the other end, then providing it with a numeric code is a
    definite advantage. It still might need additional information,
    however, and you should consider some means of providing this as
    well. Transmission should generally be as text however, but in
    such cases, I'd limit the text to a highly restricted set of
    characters, unless the additional information required more.

    For logging, it depends on the context. I don't think there are
    any absolute rules. But on the server side, I'd recommend
    logging before the exception is thrown (perhaps in the
    constructor of the exception, but more likely by means of using
    a macro to throw the exception---this is also a case where
    you'll want Alf's possibility of throwing the exception from
    within the exception).

    For interactive users, the message should be formatted in the
    user interface, using the information in the exception---the
    exception itself should not be concerned with what the user
    should see, or how the error will be presented to the user (but
    it must carry all of the information that might be needed).

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Aug 13, 2009
    #19
  20. mzdude

    James Kanze Guest

    On Aug 14, 3:15 pm, (Yannick Tremblay) wrote:
    > In article <>,
    > Pete Becker <> wrote:


    [...]
    > I have a more pragmatic approach to that: simply don't let
    > exceptions propagate accros threads. I can't say that I have
    > encounter a real hard case where it was needed.


    Me neither, and that's surely a valid choice for a lot of
    applications. But probably not all.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Aug 14, 2009
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. earthling
    Replies:
    0
    Views:
    375
    earthling
    Mar 15, 2005
  2. Johan Tibell
    Replies:
    66
    Views:
    1,009
    Chris Torek
    Aug 7, 2006
  3. Ken Varn
    Replies:
    0
    Views:
    424
    Ken Varn
    Apr 26, 2004
  4. Bas van Gils

    a matter of style

    Bas van Gils, Jun 11, 2007, in forum: Ruby
    Replies:
    21
    Views:
    310
    Chad Perrin
    Jun 13, 2007
  5. Anders Wegge Keller

    Conditional declaration (A matter of style)

    Anders Wegge Keller, Oct 13, 2012, in forum: C Programming
    Replies:
    3
    Views:
    351
    Kaz Kylheku
    Oct 13, 2012
Loading...

Share This Page