I have a "Status" class in C#, used like this:
Status MyFunction()
{
if(...) // something bad
return new Status(false, "Something went wrong")
else
return new Status(true, "OK");
}
You get the idea.
All callers of MyFunction should check the returned Status:
Status myStatus = MyFunction();
if ( ! myStatus.IsOK() )
// handle it, show a message,...
Lazy callers however can ignore the Status.
MyFunction(); // call function and ignore returned Status
or
{
Status myStatus = MyFunction();
} // lose all references to myStatus, without calling IsOK() on it
Is it possible to make this impossible? e.g. an throw exception
In general: is it possible to write a C# class on which you have to call a certain function?
In the C++ version of the Status class, I can write a test on some private bool bIsChecked in the destructor and ring some bells when someone doesn't check this instance.
What is the equivalent option in C#?
I read somewhere that "You don't want a destructor in your C# class"
Is the Dispose method of the IDisposable interface an option?
In this case there are no unmanaged resources to free.
Additionally, it is not determined when the GC will dispose the object.
When it eventually gets disposed, is it still possible to know where and when you ignored that specific Status instance?
The "using" keyword does help, but again, it is not required for lazy callers.
I know this doesn't answer your question directly, but if "something went wrong" within your function (unexpected circumstances) I think you should be throwing an exception rather than using status return codes.
Then leave it up to the caller to catch and handle this exception if it can, or allow it to propogate if the caller is unable to handle the situation.
The exception thrown could be of a custom type if this is appropriate.
For expected alternative results, I agree with #Jon Limjap's suggestion. I'm fond of a bool return type and prefixing the method name with "Try", a la:
bool TryMyFunction(out Status status)
{
}
If you really want to require the user to retrieve the result of MyFunction, you might want to void it instead and use an out or ref variable, e.g.,
void MyFunction(out Status status)
{
}
It might look ugly but at least it ensures that a variable is passed into the function that will pick up the result you need it to pick up.
#Ian,
The problem with exceptions is that if it's something that happens a little too often, you might be spending too much system resources for the exception. An exception really should be used for exceptional errors, not totally expected messages.
Even System.Net.WebRequest throws an exception when the returned HTTP status code is an error code. The typical way to handle it is to wrap a try/catch around it. You can still ignore the status code in the catch block.
You could, however, have a parameter of Action< Status> so that the caller is forced to pass a callback function that accepts a status and then checking to see if they called it.
void MyFunction(Action<Status> callback)
{ bool errorHappened = false;
if (somethingBadHappend) errorHappened = true;
Status status = (errorHappend)
? new Status(false, "Something went wrong")
: new Status(true, "OK");
callback(status)
if (!status.isOkWasCalled)
throw new Exception("Please call IsOK() on Status").
}
MyFunction(status => if (!status.IsOK()) onerror());
If you're worried about them calling IsOK() without doing anything, use Expression< Func< Status,bool>> instead and then you can analyse the lambda to see what they do with the status:
void MyFunction(Expression<Func<Status,bool>> callback)
{ if (!visitCallbackExpressionTreeAndCheckForIsOKHandlingPattern(callback))
throw new Exception
("Please handle any error statuses in your callback");
bool errorHappened = false;
if (somethingBadHappend) errorHappened = true;
Status status = (errorHappend)
? new Status(false, "Something went wrong")
: new Status(true, "OK");
callback.Compile()(status);
}
MyFunction(status => status.IsOK() ? true : onerror());
Or forego the status class altogether and make them pass in one delegate for success and another one for an error:
void MyFunction(Action success, Action error)
{ if (somethingBadHappened) error(); else success();
}
MyFunction(()=>;,()=>handleError());
I am fairly certain you can't get the effect you want as a return value from a method. C# just can't do some of the things C++ can. However, a somewhat ugly way to get a similar effect is the following:
using System;
public class Example
{
public class Toy
{
private bool inCupboard = false;
public void Play() { Console.WriteLine("Playing."); }
public void PutAway() { inCupboard = true; }
public bool IsInCupboard { get { return inCupboard; } }
}
public delegate void ToyUseCallback(Toy toy);
public class Parent
{
public static void RequestToy(ToyUseCallback callback)
{
Toy toy = new Toy();
callback(toy);
if (!toy.IsInCupboard)
{
throw new Exception("You didn't put your toy in the cupboard!");
}
}
}
public class Child
{
public static void Play()
{
Parent.RequestToy(delegate(Toy toy)
{
toy.Play();
// Oops! Forgot to put the toy away!
});
}
}
public static void Main()
{
Child.Play();
Console.ReadLine();
}
}
In the very simple example, you get an instance of Toy by calling Parent.RequestToy, and passing it a delegate. Instead of returning the toy, the method immediately calls the delegate with the toy, which must call PutAway before it returns, or the RequestToy method will throw an exception. I make no claims as to the wisdom of using this technique -- indeed in all "something went wrong" examples an exception is almost certainly a better bet -- but I think it comes about as close as you can get to your original request.
Using Status as a return value remembers me of the "old days" of C programming, when you returned an integer below 0 if something didn't work.
Wouldn't it be better if you throw an exception when (as you put it) something went wrong? If some "lazy code" doesn't catch your exception, you'll know for sure.
Instead of forcing someone to check the status, I think you should assume the programmer is aware of this risks of not doing so and has a reason for taking that course of action. You don't know how the function is going to be used in the future and placing a limitation like that only restricts the possibilities.
That would sure be nice to have the compiler check that rather than through an expression. :/
Don't see any way to do that though...
You can throw an exception by:
throw MyException;
[global::System.Serializable]
public class MyException : Exception
{
//
// For guidelines regarding the creation of new exception types, see
// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/cpconerrorraisinghandlingguidelines.asp
// and
// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncscol/html/csharp07192001.asp
//
public MyException () { }
public MyException ( string message ) : base( message ) { }
public MyException ( string message, Exception inner ) : base( message, inner ) { }
protected MyException (
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context )
: base( info, context ) { }
}
The above exception is fully customizable to your requirements.
One thing I would say is this, I would leave it to the caller to check the return code, it is their responsability you just provide the means and interface. Also, It is a lot more efficient to use return codes and check the status with an if statement rather than trhowing exceptions. If it really is an Exceptional circumstance, then by all means throw away... but say if you failed to open a device, then it might be more prudent to stick with the return code.
#Paul you could do it at compile time with Extensible C#.
GCC has a warn_unused_result attribute which is ideal for this sort of thing. Perhaps the Microsoft compilers have something similar.
One pattern which may sometimes be helpful if the object to which code issues requests will only be used by a single thread(*) is to have the object keep an error state, and say that if an operation fails the object will be unusable until the error state is reset (future requests should fail immediately, preferably by throwing an immediate exception which includes information about both the previous failure and the new request). In cases where calling code happens to anticipate a problem, this may allow the calling code to handle the problem more cleanly than if an exception were thrown; problems which are not ignored by the calling code will generally end up triggering an exception pretty soon after they occur.
(*) If a resource will be accessed by multiple threads, create a wrapper object for each thread, and have each thread's requests go through its own wrapper.
This pattern is usable even in contexts where exceptions aren't, and may sometimes be very practical in such cases. In general, however, some variation of the try/do pattern is usually better. Have methods throw exception on failure unless the caller explicitly indicates (by using a TryXX method) that failures are expected. If callers say failures are expected but don't handle them, that's their problem. One could combine the try/do with a second layer of protection using the scheme above, but I'm not sure whether it would be worth the cost.
Related
Say you were calling a method similar to the following, which you know is only ever going to throw one of 2 exceptions:
public static void ExceptionDemo(string input)
{
if (input == null)
throw new ArgumentNullException("input");
if (input.Contains(","))
throw new ArgumentException("input cannot contain the comma character");
// ...
// ... Some really impressive code here
// ...
}
A real life example of a method which does this is Membership.GetUser (String)
Which of the following would you use to call the method and handle the exceptions:
Method 1 (check the input param first first)
public static void Example1(string input)
{
// validate the input first and make sure that the exceptions could never occur
// no [try/catch] required
if (input != null && !input.Contains(","))
{
ExceptionDemo(input);
}
else
{
Console.WriteLine("input cannot be null or contain the comma character");
}
}
Method 2 (wrap the call in a try / catch)
public static void Example2(string input)
{
// try catch block with no validation of the input
try
{
ExceptionDemo(input);
}
catch (ArgumentNullException)
{
Console.WriteLine("input cannot be null");
}
catch (ArgumentException)
{
Console.WriteLine("input cannot contain the comma character");
}
}
I've had both methods taught over the years and wondered what the general best practise was for this scenario.
Update
Several posters were focusing on the method throwing the exceptions and not the way these exceptions were being handled, so I've provided an example of a .Net Framework method which behaves in the same way (Membership.GetUser (String))
So, to clarify my question, if you we're calling Membership.GetUser(input) how would you handle the possible exceptions, Method 1, 2 or something else?
Thanks
It depends, but generally, neither method presented is good. As has been said, in the first case, you are duplicating code. In the second, you are catching the exception without actually doing anything about it - not even rethrowing, just swallowing it. If you want just to log it or display some message, normally you should implement a global handler/logger using AppDomain.UnhandledException and do it there; this way, you don't have to pollute your code with unnecessary try/catch blocks.
The real question here is whether or not input being null or containing ',' is really an exceptional behavior in your specific case - e.g. if this is some GUI-entered string, then this should normally not result in an exception throw (end-user mistakes should be expected) and should be handled appropriately (e.g. with a warning to re-entry the input). In such case, using if statements to validate the input is the proper way. However, if input being null or containing ',' is an actual exceptional behavior (say, an API problem which indicates something's broken or missing) then throwing exception is ok. In this case, you can simply call ExceptionDemo(input) without try/catch. If you want to actually do something about the exception (e.g. change the input in some way), then use try/catch.
Callers should not assume anything about code they're calling.
Your first example is bad, because you're duplicating code: the caller performs almost (string.INOE() vs string == null) the same check as the callee (until either of them changes).
The second example is extremely bad as it ignores the thrown exceptions and gives its own interpretation to them.
As usual: it depends. If you have a properly layered application where the method calls are in your UI layer, you do want to just catch the exception the method throws: you'll want to display those errors to the user.
It depends on how many times ExceptionDemo is called and who it is exposed to. If it was used extensively, you wouldn't want to check the conditions before calling ExceptionDemo, when you know (and document) that ExceptionDemo does the checks anyway.
Given the return type is void, what about changing ExceptionDemo to have no effect if the input is wrong?
(Did you notice that you are stricter in Method 1 - the empty string is not a valid input, but in Method 2 it is)
I would recommend standard and generic structure as below :
public static void Operation(object input)
{
try
{
ValidateInput(input);
//Do Operation
}
catch (MySpecificException subSubExceptionType) //Catch most specific exceptions
{
//Log or process exception
throw;
}
catch (MySpecificException subExceptionType) //Catch specific exception
{
//Log or process exception
}
catch (Exception exceptionType) //Catch most generic exception
{
//Log or process exception
}
finally
{
//Release the resources
}
}
private static void ValidateInput(object input)
{
if(input == null)
throw new NoNullAllowedException();
//Check if properties of input are as expected. If not as expected then throw specific exception with specific message
}
I'm going to provide a simple example of what I'm trying to do -- hopefully it is possible?
I basically have a class that does a whole ton of formatting/analyzing to the data. As a result, there a lot of things that can go wrong with this. The problem I have is handling the class when things go wrong. I want all execution of this class to stop once an error has occurred.
This class (AnalyzingStuff) is called from a parent form that does various things based on the result of this classes execution.
Ideally, I would fire an event named say "ABORT".
So in this code here I do the following:
Class AnalyzingStuff{
public event EventHandler ABORT;
public AnalyzingStuff(){
for(int i = 0; i < 999999; i ++){
AnalyzeSomeStuff();
AnalyzerSomeOtherStuff();
}
MoreStuff();
OtherStuff();
}
private void AnalyzeSomeStuff(){
if(someconditionNotMet){
//EXIT OUT OF THIS CLASS, STOP EXECUTION!!!
this.ABORT.Invoke(this, null);
}
}
}
Calling this 'ABORT' event, I would stop the execution of this class (stop the loop and not do anything else). I could also catch this event handler in some other parent form. Unfortunately, I can't find any way of stopping the execution of this class.
Ideas so far:
The obvious answer is to simply set a flag and constantly check this flag over and over in multiple places, but I really don't like this approach (my current implementation). Having to check this after every single method call (there are MANY) is ugly codewise.
I thought maybe a background worker or something where you could cancel the execution of the DoWork?
Use a form as a base class for the AnalyzingStuff so I can simply call "this.Close();".
What do you think is the best approach to this situation? Are these the best solutions? Are there any other elegant solutions to what I want here or am I going completely in the wrong direction?
EDIT: I have a series of try/catch blocks used throughout this code that is used to handle different errors that can occur. Unfortunately, not all of them call for an Abort to occur so they need to be caught immediately. Therefore, try/catch not the most ideal approach.. or is it?
Don't do analysys in the constructor. Do it in a main Analyze() method.
Use exceptions. If you want to abort because of a fatal error, throw a fatal exception. That is, throw an exception that you don't catch within the scope of the main analysis method.
class Analyzer
{
public Analyzer()
{
// initialize things
}
public void Analyze()
{
// never catch a fatal exception here
try
{
AnalyzeStuff();
... optionally call more methods here ...
}
catch (NonFatalException e)
{
// handle non fatal exception
}
... optionally call more methods (wrapped in try..catch) here ...
}
private void AnalyzeStuff()
{
// do stuff
if (something nonfatal happens)
throw new NonFatalException();
if (something fatal happens)
throw new FatalException();
}
}
outside:
{
var analyzer = new Analyzer();
try
{
analyzer.Analyze();
}
catch (FatalException)
{
Console.WriteLine("Analysis failed");
}
}
If you don't like using exception this way, you can accomplish the same thing by having every analysis method return a bool:
if (!AnalyzeStuff())
return false;
if (!AnalyzeMoreStuff())
return false;
...
return true;
But you end up with a lot of return statements or a lot of braces. It's a matter of style and preference.
Could you throw an Exception if things go wrong, and run a try catch around where you call the method in the loop?
if you do this you could do stuff if the class fails (which you will put in the catch), and stuff you could do to close connections to database ++ when it is done.
or you could make the methods return an int, to tell if the execution of the method was valid. ex. return 0; is valid execution, return 1-500 would then might be different error codes. Or you might go for the simple version of passing a bool. If you need to return values from methods other than the error code you could pass these as OUT variables. example following:
Class AnalyzingStuff{
public AnalyzingStuff(){
for(int i = 0; i < 999999; i ++){
if (!AnalyzeSomeStuff() || !AnalyzerSomeOtherStuff())
break;
}
MoreStuff();
OtherStuff();
}
private bool AnalyzeSomeStuff(){
if(someconditionNotMet){
return false;
}
return true;
}
}
You can of course use your event. I just removed it for the simplicity of it.
Situation:
My application need to process the first step in the business rules (the initial try-catch statement). If an certain error occurs when the process calls the helper method during the step, I need to switch to a second process in the catch statement. The back up process uses the same helper method. If an same error occurs during the second process, I need to stop the entire process and throw the exception.
Implementation:
I was going to insert another try-catch statement into the catch statement of the first try-catch statement.
//run initial process
try
{
//initial information used in helper method
string s1 = "value 1";
//call helper method
HelperMethod(s1);
}
catch(Exception e1)
{
//backup information if first process generates an exception in the helper method
string s2 = "value 2";
//try catch statement for second process.
try
{
HelperMethod(s2);
}
catch(Exception e2)
{
throw e2;
}
}
What would be the correct design pattern to avoid code smells in this implementation?
I caused some confusion and left out that when the first process fails and switches to the second process, it will send different information to the helper method. I have updated the scenario to reflect the entire process.
If the HelperMethod needs a second try, there is nothing directly wrong with this, but your code in the catch tries to do way too much, and it destroys the stacktrace from e2.
You only need:
try
{
//call helper method
HelperMethod();
}
catch(Exception e1)
{
// maybe log e1, it is getting lost here
HelperMethod();
}
I wouldn't say it is bad, although I'd almost certainly refactor the second block of code into a second method, so keep it comprehensible. And probably catch something more specific than Exception. A second try is sometimes necessary, especially for things like Dispose() implementations that might themselves throw (WCF, I'm looking at you).
The general idea putting a try-catch inside the catch of a parent try-catch doesn't seem like a code-smell to me. I can think of other legitimate reasons for doing this - for instance, when cleaning up an operation that failed where you do not want to ever throw another error (such as if the clean-up operation also fails). Your implementation, however, raises two questions for me: 1) Wim's comment, and 2) do you really want to entirely disregard why the operation originally failed (the e1 Exception)? Whether the second process succeeds or fails, your code does nothing with the original exception.
Generally speaking, this isn't a problem, and it isn't a code smell that I know of.
With that said, you may want to look at handling the error within your first helper method instead of just throwing it (and, thus, handling the call to the second helper method in there). That's only if it makes sense, but it is a possible change.
Yes, a more general pattern is have the basic method include an overload that accepts an int attempt parameter, and then conditionally call itself recursively.
private void MyMethod (parameterList)
{ MyMethod(ParameterList, 0)l }
private void MyMethod(ParameterList, int attempt)
{
try { HelperMethod(); }
catch(SomeSpecificException)
{
if (attempt < MAXATTEMPTS)
MyMethod(ParameterList, ++attempt);
else throw;
}
}
It shouldn't be that bad. Just document clearly why you're doing it, and most DEFINITELY try catching a more specific Exception type.
If you need some retry mechanism, which it looks like, you may want to explore different techniques, looping with delays etc.
It would be a little clearer if you called a different function in the catch so that a reader doesn't think you're just retrying the same function, as is, over again. If there's state happening that's not being shown in your example, you should document it carefully, at a minimum.
You also shouldn't throw e2; like that: you should simply throw; if you're going to work with the exception you caught at all. If not, you shouldn't try/catch.
Where you do not reference e1, you should simply catch (Exception) or better still catch (YourSpecificException)
If you're doing this to try and recover from some sort of transient error, then you need to be careful about how you implement this.
For example, in an environment where you're using SQL Server Mirroring, it's possible that the server you're connected to may stop being the master mid-connection.
In that scenario, it may be valid for your application to try and reconnect, and re-execute any statements on the new master - rather than sending an error back to the caller immediately.
You need to be careful to ensure that the methods you're calling don't have their own automatic retry mechanism, and that your callers are aware there is an automatic retry built into your method. Failing to ensure this can result in scenarios where you cause a flood of retry attempts, overloading shared resources (such as Database servers).
You should also ensure you're catching exceptions specific to the transient error you're trying to retry. So, in the example I gave, SqlException, and then examining to see if the error was that the SQL connection failed because the host was no longer the master.
If you need to retry more than once, consider placing an 'automatic backoff' retry delay - the first failure is retried immediately, the second after a delay of (say) 1 second, then doubled up to a maximum of (say) 90 seconds. This should help prevent overloading resources.
I would also suggest restructuring your method so that you don't have an inner-try/catch.
For example:
bool helper_success = false;
bool automatic_retry = false;
//run initial process
try
{
//call helper method
HelperMethod();
helper_success = true;
}
catch(Exception e)
{
// check if e is a transient exception. If so, set automatic_retry = true
}
if (automatic_retry)
{ //try catch statement for second process.
try
{
HelperMethod();
}
catch(Exception e)
{
throw;
}
}
Here's another pattern:
// set up state for first attempt
if(!HelperMethod(false)) {
// set up state for second attempt
HelperMethod(true);
// no need to try catch since you're just throwing anyway
}
Here, HelperMethod is
bool HelperMethod(bool throwOnFailure)
and the return value indicates whether or not success occurred (i.e., false indicates failure and true indicates success). You could also do:
// could wrap in try/catch
HelperMethod(2, stateChanger);
where HelperMethod is
void HelperMethod(int numberOfTries, StateChanger[] stateChanger)
where numberOfTries indicates the number of times to try before throwing an exception and StateChanger[] is an array of delegates that will change the state for you between calls (i.e., stateChanger[0] is called before the first attempt, stateChanger[1] is called before the second attempt, etc.)
This last option indicates that you might have a smelly setup though. It looks like the class that is encapsulating this process is responsible for both keeping track of state (which employee to look up) as well as looking up the employee (HelperMethod). By SRP, these should be separate.
Of course, you need to a catch a more specific exception than you currently are (don't catch the base class Exception!) and you should just throw instead of throw e if you need to rethrow the exception after logging, cleanup, etc.
You could emulate C#'s TryParse method signatures:
class Program
{
static void Main(string[] args)
{
Exception ex;
Console.WriteLine("trying 'ex'");
if (TryHelper("ex", out ex))
{
Console.WriteLine("'ex' worked");
}
else
{
Console.WriteLine("'ex' failed: " + ex.Message);
Console.WriteLine("trying 'test'");
if (TryHelper("test", out ex))
{
Console.WriteLine("'test' worked");
}
else
{
Console.WriteLine("'test' failed: " + ex.Message);
throw ex;
}
}
}
private static bool TryHelper(string s, out Exception result)
{
try
{
HelperMethod(s);
result = null;
return true;
}
catch (Exception ex)
{
// log here to preserve stack trace
result = ex;
return false;
}
}
private static void HelperMethod(string s)
{
if (s.Equals("ex"))
{
throw new Exception("s can be anything except 'ex'");
}
}
}
Another way is to flatten the try/catch blocks, useful if you're using some exception-happy API:
public void Foo()
{
try
{
HelperMethod("value 1");
return; // finished
}
catch (Exception e)
{
// possibly log exception
}
try
{
HelperMethod("value 2");
return; // finished
}
catch (Exception e)
{
// possibly log exception
}
// ... more here if needed
}
An option for retry (that most people will probably flame) would be to use a goto. C# doesn't have filtered exceptions but this could be used in a similar manner.
const int MAX_RETRY = 3;
public static void DoWork()
{
//Do Something
}
public static void DoWorkWithRetry()
{
var #try = 0;
retry:
try
{
DoWork();
}
catch (Exception)
{
#try++;
if (#try < MAX_RETRY)
goto retry;
throw;
}
}
In this case you know this "exception" probably will happen so I would prefer a simple approach an leave exceptions for the unknown events.
//run initial process
try
{
//initial information used in helper method
string s1 = "value 1";
//call helper method
if(!HelperMethod(s1))
{
//backup information if first process generates an exception in the helper method
string s2 = "value 2";
if(!HelperMethod(s2))
{
return ErrorOfSomeKind;
}
}
return Ok;
}
catch(ApplicationException ex)
{
throw;
}
I know that I've done the above nested try catch recently to handle decoding data where two third party libraries throw exceptions on failure to decode (Try json decode, then try base64 decode), but my preference is to have functions return a value which can be checked.
I generally only use the throwing of exceptions to exit early and notify something up the chain about the error if it's fatal to the process.
If a function is unable to provide a meaningful response, that is not typically a fatal problem (Unlike bad input data).
It seems like the main risk in nested try catch is that you also end up catching all the other (maybe important) exceptions that might occur.
In many cases in web applications you would need to return an error message, rather than simple true/false result. One would use exceptions for that, but I consider exceptions to be an indication of, you know, exceptional behavior. Let's take a Register() function for a class User for instance. If it was successful we can simply return true, but if something went wrong we would like to know what exactly: "passwords don't match", "e-mail is in invalid format" and so on (could be an error code instead of a message, doesn't matter).
The question is what is the best practice for returning such error messages in C# and .Net? There might be a struct ready, something like:
public struct Result {
public bool OK;
public string Message;
}
Or perhaps I should just use a parameter in the function? Like Register(out string Message).
Update. This pretty much describes everything I need: http://blogs.msdn.com/kcwalina/archive/2005/03/16/396787.aspx
If it's for validation purposes I would recommend you the excellent Fluent Validation library.
Quote from the site:
using FluentValidation;
public class CustomerValidator: AbstractValidator<Customer> {
public CustomerValidator() {
RuleFor(customer => customer.Surname).NotEmpty();
RuleFor(customer => customer.Forename).NotEmpty().WithMessage("Please specify a first name");
RuleFor(customer => customer.Company).NotNull();
RuleFor(customer => customer.Discount).NotEqual(0).When(customer => customer.HasDiscount);
RuleFor(customer => customer.Address).Length(20, 250);
RuleFor(customer => customer.Postcode).Must(BeAValidPostcode).WithMessage("Please specify a valid postcode");
}
private bool BeAValidPostcode(string postcode) {
// custom postcode validating logic goes here
}
}
Customer customer = new Customer();
CustomerValidator validator = new CustomerValidator();
ValidationResult results = validator.Validate(customer);
bool validationSucceeded = results.IsValid;
IList<ValidationFailure> failures = results.Errors;
I think exceptions can and should be used here.
You can put your Register() call in a try/catch block therefore preventing application execution stop. In the catch block you will analyze what exactly got wrong and return an appropriate message.
I think exception should be used when it comes to program mistakes and IO communication.
This means:
non-validated input
a bug in the software. (adding 2 equal keys to dictionaries)
disk access/network/cross application/ etc
For a Register method i should either use a boolean for result checking.
if(Register("someone", "password"))
{
// success
}
else
{
// failed
}
or if you like more details on the result, specify a result enum:
public enum RegisterResult
{
Success,
BadUsernamePassword,
PasswordTooShort
}
RegisterResult result = Register("someone", "password");
switch(result)
{
case(RegisterResult.Success):
// success
break;
case(RegisterResult.BadUsernamePassword):
// failed
break;
case(RegisterResult.PasswordTooShort):
// failed
break;
}
If you need more information like a userId, you should define it as a output parameter
int userId = 0;
RegisterResult result = Register("someone", "password", out userId);
etc...
So if an exception is thrown, this means 1 of 3 things.
Some of the input (by user) is not validated. ' (negligence of the programmer)
There is bug in it. (like accessing disposed objects or something serious. etc.)
There is an IO problem. (connecting lost from database.. etc)
I advice u to use exceptions only in exceptional situations. A bad login isn't an exception, it's a user fault.
Regards,
Jeroen
Throwing exceptions creates CPU utilization while adding all call stack and setting other fields of exception class.
I prefer not to throw Exceptions. If it is really casual error like say Argument is null,i would go for struct with an ExceptionMessage field with it.
But it is better to type-value check before calling a method and expecting primitive types to return from the method since you need a boolean value return to.
I would like to use a COM object in my application.
How can I make sure the object is registered in the machine?
The only solution I found (also on SO) was to use a try-catch block around the initialization:
try {
Foo.Bar COM_oObject = new Foo.Bar();
} catch (Exception ee) {
// Something went wrong during init of COM object
}
Can I do it in any other way?
I feel its wrong to deal with an error by expecting it and reporting it, I would rather know I will fail and avoid it to begin with.
You are using exception handling the right way: to fail gracefully from a specific situation that you know how to recover from.
There's not a problem with using try-catch in this case, but you could at least catch more specifically : ComException.
"I feel its wrong to deal with an error by expecting it and reporting it"
Isn't it exactly the purpose of try-catch? BTW, an Exception occurs when something really bad has happened and since it is a pretty bad thing that the COM object you are referring to is not registered, therefore, an Exception is the perfect solution. And you can't handle an exception in any other way.
I think this is the right way to do it.
If you know your component's ProgId. You could try this trick
comType = Type.GetTypeFromProgID(progID,true/*throw on error*/);
If you're doing this a lot and wish you had a non-exception throwing equivalent, try:
public static class Catching<TException> where TException : Exception
{
public static bool Try<T>(Func<T> func, out T result)
{
try
{
result = func();
return true;
}
catch (TException x)
{
// log exception message (with call stacks
// and all InnerExceptions)
}
result = default(T);
return false;
}
public static T Try<T>(Func<T> func, T defaultValue)
{
T result;
if (Try(func, out result))
return result;
return defaultValue;
}
}
So now you can do this:
Foo.Bar newObj;
if (!Catching<ComException>.Try(() => new Foo.Bar(), out newObj))
{
// didn't work.
}
Or if you have a default object stored in defaultMyInterface you'd use to implement an interface if there's nothing better:
IMyInterface i = Catching<ComException>.Try(() => new Foo.Bar() as IMyInterface,
defaultMyInterface);
You can also do this, in a completely different scenario:
int queueSize = Catching<MyParsingException>
.Try(() => Parse(optionStr, "QueueSize"), 5);
If Parse throws a MyParsingException, queueSize will default to 5, otherwise the returned value from Parse is used (or any other exception will propagate normally, which is usually what you want with an unexpected exception).
This helps to avoid breaking up the flow of the code, and also centralises your logging policy.