Error: an out parameter or a return value?



  • <FONT face=Tahoma>I'm trying to develop an asp.net application. In this application, i want to detect if an error has occurred inside a method, although the method already handles the error inside. Also note that some methods return values others do not and some accept parameters and others don't.

    Now i'm thinking on doing one of the following:</FONT><FONT face=Tahoma> </FONT>

    • <FONT face=Tahoma>using global boolean "HasError" variables</FONT>
    • <FONT face=Tahoma>return boolean "HasError" values on each method (in this case i'll just make the value-returning methods into a method that uses out parameters instead)</FONT>
    • <FONT face=Tahoma>include a "HasError" boolean out parameter on each method</FONT>

    <FONT face=Tahoma>Are there any other and more efficient (maintenance-wise) ways to do that? This is just a small, personal application, you know, those that automate some of your daily routines. :)

    Thanks!



    </FONT>



  • I think your design is flawed.

    The best option is to return the success status where appropriate. Other than that, it's generally not a good idea to pass too much information around, as this would create dependencies that make maintainance more difficult.



  • I've used a system where there'd be a global error array, filled with error messages.

    The methods and functions would try to gracefully catch errors, and add a readable message to the errors array.

    After that, the errors array can be easily stored or displayed or whatever, after execution.



  • @xrT said:

    <FONT face=Tahoma>I'm trying to develop an asp.net application. In this application, i want to detect if an error has occurred inside a method, although the method already handles the error inside. Also note that some methods return values others do not and some accept parameters and others don't.

    Now i'm thinking on doing one of the following:</FONT><FONT face=Tahoma> </FONT>

    • <FONT face=Tahoma>using global boolean "HasError" variables</FONT>
    • <FONT face=Tahoma>return boolean "HasError" values on each method (in this case i'll just make the value-returning methods into a method that uses out parameters instead)</FONT>
    • <FONT face=Tahoma>include a "HasError" boolean out parameter on each method</FONT>

    <FONT face=Tahoma>Are there any other and more efficient (maintenance-wise) ways to do that? This is just a small, personal application, you know, those that automate some of your daily routines. :)

    Thanks!



    </FONT>

    How about an exception?



  • if you want to know if a function that doesn't return anything has an error make it return a boolean.  if you want to check if a function that returns something had an error make it return a sentinel value like -1 or NaN or EOF or NULL or whatever makes sense for that function.  I can't think of a function that you want to return meaningful information from (beyond an error description) and continue running through the whole method even after it encounters an error.



  • @ammoQ said:

    I think your design is flawed.

    The best option is to return the success status where appropriate. Other than that, it's generally not a good idea to pass too much information around, as this would create dependencies that make maintainance more difficult.


    <FONT face=Tahoma>I agree about the passing too much information part, so ok, let's say we've narrowed down the methods that needs to have error checking, for example 2 methods, and one of those methods returns a value. What should be used then? :-/ Probably the "global" one like dhromed suggested is the most suitable...<FONT face="Times New Roman">
    </FONT>

    <FONT face="Times New Roman">@masklinn said:
    </FONT>

    How about an exception?




    noted... :)



    </FONT>


  • @tster said:

    if you want to know if a function that doesn't return anything has an error make it return a boolean.  if you want to check if a function that returns something had an error make it return a sentinel value like -1 or NaN or EOF or NULL or whatever makes sense for that function.  I can't think of a function that you want to return meaningful information from (beyond an error description) and continue running through the whole method even after it encounters an error.


    <FONT face=Tahoma>It's more like a "run and handle errors for yourself, just tell me if you encounter one" sort of thing... :)
    I'll look into this too and see what works better for me...
    </FONT>




  • @xrT said:

    <font face="Tahoma">let's say we've narrowed down the methods that needs to have error checking, for example 2 methods, and one of those methods returns a value. What should be used then? :-/ Probably the "global" one like dhromed suggested is the most suitable</font>


    IMO the "global" collection is suitable if all you want is to collect the error messages through the call stack, so to output it to the user. For example, you could have an output like
        transfer of funds failed
        could not update customer status
        record locked
    where each line is created at a different abstraction level (i.e. function) in the process.
    Your program should not try to process ("understand") these error messages.

    Exceptions are a possibility, but they should be used for "exceptional" circumstances only. Incorrect user input is definitely not exceptional, but a smoking database server is.

    For the problem with 2 functions, my approach is to return a return value for success or not (e.g. 0=success, everything else is an error code); if necessary, an error description can be returned through an out parameter. If a function is supposed to return a usefull value, in some cases you could return a "special" value (e.g. null) to indicate an error; but this method should be used with care.



  • @ammoQ said:

    IMO the "global" collection is suitable if all you want is to collect the error messages through the call stack, so to output it to the user. For example, you could have an output like
        transfer of funds failed
        could not update customer status
        record locked
    where each line is created at a different abstraction level (i.e. function) in the process.
    Your program should not try to process ("understand") these error messages.


    <FONT face=Tahoma>this is the functionality i'm trying to do, so maybe i'll go ahead with the "global" collection and since exceptions are handled within the function itself, I think there's no need to return them... thanks!



    </FONT>



  • @ammoQ said:

    smoking database server

    How about a fully nicotine patched server?<duck>



  • @xrT said:

    @ammoQ said:
    I think your design is flawed.

    The best option is to return the success status where appropriate. Other than that, it's generally not a good idea to pass too much information around, as this would create dependencies that make maintainance more difficult.


    <FONT face=Tahoma>I agree about the passing too much information part, so ok, let's say we've narrowed down the methods that needs to have error checking, for example 2 methods, and one of those methods returns a value. What should be used then? :-/ Probably the "global" one like dhromed suggested is the most suitable...<FONT face="Times New Roman">
    </FONT>
    </FONT>

    Stay away from anything Global.  All ASP.Net apps are multithreaded and you'll end up on the front page of this site if you train yourself to use globals for error aggregation in an ASP.Net application.  Even sticking an errors collection in Session is asking for trouble if a user opens two browser windows or if you end up with something out of the ordinary like frames or popups.  I'd find some type of organization for the methods that need this functionality, then instantiate some sort of "CallContext" object.  The methods would be methods on the "CallContext" object and errors would be aggregated as a property of that object.  Then error clearing and checking would be methods on the "CallContext".

    I'd also caution against the whole multi-error approach.  By definition, in order to create a multi-error system like this, you have to have silent errors (errors that you have to intentionally look for).  Passing an error as a parameter or a return code is asking for trouble.... If you forget to check it, all hell breaks loose.  C programmers get away with it because everything works this way in C, so they don't forget (well, sometimes they still do).  If you forget about an exception, it'll come and find you.  Besides, then how do you return a legitimate value?  That makes code ugly, this:

    <FONT face="Courier New">try
      {  MyLabel.Text = MyMethod(MyParameter).toString();  }
    catch { ... }</FONT>

    becomes:

    <FONT face="Courier New">int ret;
    if( MyMethod(MyParameter, ret) !=0 )
      {  MyLabel.Text = ret.toString();  }
    else
      { ... }</FONT>

    And this:

    <FONT face="Courier New">

    <FONT face="Courier New">try
      {  MyLabel.Text = MyMethod2(MyMethod(MyParameter)).toString();  }
    catch (ExType1 ex) { ... }
    catch (ExType2 ex) { ... }</FONT>

    <FONT face="Times New Roman">Becomes a total mess.</FONT>

    </FONT>

    So, for the methods that perform the actual work, I'd strongly recommend exceptions.  Then for those specific processes where you want to collect a bunch of errors, wrap the process in a big method and throw a custom exception that contains a collection of thing that went wrong.

    Take all of the advice to avoid exception with a grain of salt.  It's realllllllllllllllllllllllly hard to have enough exceptions to significantly slow down a system, unless everything always throws an exception.  Besides, it's worth buying a little extra harware to avoid the pain of debugging silent failures.  Also, 95% of all business type apps are IO bound, not CPU or memory bound.  That means that even if a system is running at 100% of capacity, it's unlikely that a significant exception load will impact performance at all.  Exceptions are just objects and they consume CPU time and memory.



  • @jsmith said:


    Stay away from anything Global.  ...

    <FONT face=Tahoma>I agree about staying away from Global variables in ASP.NET. Although I think it would be better to use a "wrapper" object to collect error information, what i'm trying to do is just a small personal app so I think using Global for myself would be fine. I wouldn't do this in an actual business app though.

    And it's maintainable enough (I know that I have to check this global variable after some calls), at least for me...</FONT>


    @jsmith said:

    <FONT face="Courier New"><FONT face="Times New Roman">... Becomes a total mess.

    <FONT face=Tahoma>I know, specially if undocumented... :)</FONT>


    @jsmith said:

    </FONT></FONT>... unless everything always throws an exception.  ....

    <FONT face=Tahoma>Come to think of it, this is just a personal app and the methods should not encounter errors / exceptions, unless something really apart from normal is happening (like smoking servers, yikes!) :)

    Maybe I'm thinking too much about this as "the way real apps should be made"... But I think its a good thing to practice that even for small apps and eventually make it a habit specially if doing some real business apps...

    Thanks for all your inputs!



    </FONT>



  • I think first we would have to know why a method would claim to return successfully but actually suffer an internal error; if it's handled the error, why do we care?  If it hasn't handled the error, why is it returning successfully?

    Maybe if these questions were answered we could provide a sensible solution.

     



  • @DrPizza said:

    I think first we would have to know why a method would claim to return successfully but actually suffer an internal error; if it's handled the error, why do we care?  If it hasn't handled the error, why is it returning successfully?

    Maybe if these questions were answered we could provide a sensible solution.

     


    <FONT face=Tahoma>The design is that the application will read a couple of settings from a file and when the app has an error reading the file (incorrect format, file not found, etc), the app will set the settings to default values. However I want the calling method to know whether the settings are actually loaded or is just set with the default values for the purpose of alerting the user.



    </FONT>


  • How about using an additional "setting" called "usedDefaultValues" or something like that?



  • The design is that the application will read a couple of settings from a file and when the app has an error reading the file (incorrect format, file not found, etc), the app will set the settings to default values. However I want the calling method to know whether the settings are actually loaded or is just set with the default values for the purpose of alerting the user.

    Take the "defaulting" mechanism out of the configuration file reader, and instead have that simply throw an exception (or return a failure) if it can't find the value requested for whatever reason?  After all, since you want defaulted-in values to behave differently than user-specified ones, it seems sensible to separate the code.


  • @xrT said:

    <font face="Tahoma">I'm trying to develop an asp.net application. In this application, i want to detect if an error has occurred inside a method, although the method already handles the error inside. Also note that some methods return values others do not and some accept parameters and others don't.

    Now i'm thinking on doing one of the following:</font><font face="Tahoma"> </font>

    • <font face="Tahoma">using global boolean "HasError" variables</font>
    • <font face="Tahoma">return boolean "HasError" values on each method (in this case i'll just make the value-returning methods into a method that uses out parameters instead)</font>
    • <font face="Tahoma">include a "HasError" boolean out parameter on each method</font>

    <font face="Tahoma">Are there any other and more efficient (maintenance-wise) ways to do that? This is just a small, personal application, you know, those that automate some of your daily routines. :)

    Thanks!



    </font>



    It was stated already but, EXCEPTIONS. They are there for this exact reason. Use them. Erros Codes are out-dated in .NET.


  • @DrPizza said:

    Take the "defaulting" mechanism out of the configuration file reader, and instead have that simply throw an exception (or return a failure) if it can't find the value requested for whatever reason?  After all, since you want defaulted-in values to behave differently than user-specified ones, it seems sensible to separate the code.

    <FONT face=Tahoma>The reason I took the configuration reading with the defaulting mechanism is that I wanted to confine the initialization of the settings. This method initializes the app settings, and defaults it if something goes wrong. I only have to know if it was set to default or not.

    But based on most suggestions, I think it became clearer to me (and easier I think) to just throw exceptions (which are handled to give some info to the user anyway) and then just call a defaulting method for that type of exception.

    Although this app, as I stated before, is just small, my current implementation should be enough. But I'll definitely look at throwing exceptions on the next release, if there's any. :)</FONT>


Log in to reply