Error communication and recovery approaches in .NET

后端 未结 3 1697
青春惊慌失措
青春惊慌失措 2021-01-16 06:53

I am trying to do error communication and recovery in my C# code without using Exceptions. To give an example, suppose there is a Func A, which can be called by Func B or Fu

3条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2021-01-16 07:31

    "is it the way professional libraries are written?"

    No, professional libraries are written by using exceptions for error handling - I am not sure if there is a pattern for using your suggested approach, but I consider it an anti-pattern (in .NET). After all, .NET itself is a professional framework and it uses exceptions. Besides, .NET developers are used to exceptions. Do you think that your library is really that special to force the users to learn completely different way of error handling?

    What you just did is reinvent the COM error handling. If that is what you want to do then check this and ISupportErrorInfo interface for some ideas.

    Why do you want to do this? I bet it is a performance 'optimization'.

    Fear of performance issues with regard to exception handling is almost always a premature optimization. You will create an awkward API where each return value must be handled via ref/out parameters and which will hurt every user of your lib, just to solve the problem which likely doesn't exist at all.

    "Func A may not know whether the caller function will have the intelligence to recover from the error or not, so I do not want to throw exceptions"

    So you want to ensure that caller silently allows FuncA to mess up the system invariants and caller just goes on happily? It will just make it much harder to debug seemingly impossible bug which happens in another function later on due to this.

    There are scenarios where it makes sense to avoid exceptions, but there should be a good justification for that. Exceptions are good idea.

    EDIT: I see that you have added that you "have read many other articles also, which suggest not to use exceptions for code flow control". That is correct, exceptions in .NET are not for code flow but for error handling.

    You ask:

    If Func A calls Func B,C,D,E,F and it has to encapsulate each call with try catch because it can recover from error or it will still like to execute remaining function calls, then is not so many try catch statements awkward

    not more than alternative. You are making a mistake that you can simple handle all errors returned from functions in a same way but you usually can't.

    Consider if you need to handle every function separately - worst case scenario and code is usually not written like that:

    Result x, y;
    try {
       x = Function1();
    }
    catch(SomeException e) {
       // handle error   
    }
    try {
       y = Function2();
    }
    catch(SomeOtherException e) {
       // handle error   
    }
    

    against:

    int error;
    Result x, y;
    error = Function1(out x);
    if(error != SOME_KNOWN_ISSUE) {
       // handle error    
    }
    error = Function2(out y);
    if(error != SOME_KNOWN_ISSUE) {
       // handle error
    }
    

    not a big difference. please don't tell me that you would not check the error code. However, if you decide to ignore all errors (a horrible idea) then exceptions are simpler:

    try {
        var x = Function1();
        var y = Function2();    
        var z = Function3();
    }
    catch Exception() { you still can see the message here and possibly rethrow }
    

    vs

    Result1 r1;
    Function1(out r1);
    Result2 r2;
    Function2(out r2);
    Result3 r3;
    Function3(out r3);
    // and here you still don't know whether there was an error
    

    Can you elaborate what do you mean by "I need predictability with regard to time constraints"?

    in some system level software or realtime stuff, you can't afford stack unwinding related to exception handling, as you can't guarantee the duration, and that could violate your timing requirements. But this is never the case in .NET as garbage collection is far worse in this regard.

    Also, when you say "In .NET I would always use the exceptions for error handling", can you explain how or what do you define as an error condition? Is a recoverable situation an error condition or not an error condition? –

    @shambulater already gave a great example in comments. In FileStream, missing file is not recoverable and it will throw. In the client of FileStream it might be recoverable or not depending on context. Some clients will ignore it, some will exit the app, some will wrap it in another exception and let someone upstream to decide.

    When will you not use exceptions?

    In those cases where I would also not return an error code.

提交回复
热议问题