C# - Exception logging and return status - c#

Modifying to make it clear:
I have a question on exception logging and graceful exit. This is in continuation with previous question. The code looks like:
string status = "0";
ClassA ObjA = new ClassA();
try
{
status = objA.Method1();
if (status != "-1")
{
status = objA.Method1();
}
}
catch (Exception Ex)
{
//Log Exception EX
}
Inside the Method1:
public string Method1()
{
string status = "0";
try
{
//Code
return "0";
}
catch (Exception Ex)
{
//Log Exception with details
return "-1"
}
}
I log the Exception in the calling method and return only a status to the caller.
Should I return the Exception to the calling method or is only a status sufficient. With a status of "-1", I know there was an Exception in the called method and details of that Exception were logged in a log file.

I think it is OK to do it like that if you have a lot of status codes, otherwise you could also just throw an exception and catch it in the method higher up.
Also maybe reconsider your return type. Looks like you could be using integers, think you are opening yourself up to errors using strings.

Don't use the status return value, it is not adding anything that is useful to you.
consider,
var a = new ClassA()
try
{
a.Mehtod1();
}
catch
{
try
{
a.Method1();
}
catch (Exception ex)
{
//Log without details;
}
}
class ClassA
{
void Method1()
{
try
{
//Code
}
catch (Exception ex)
{
//Log with details
throw;
}
}
}
This code achieves the same functionality but leaves the return code of the functions for something useful and non exceptional.
More generally, I suggest that you should have one catch all handler at the top level of your application that deals with logging, or at most one per public entry point. Other handlers should deal with specific exception types that they can actually "handle" (do something about.)

It all depends on the purpose and implementation of the code; sometimes it is better to allow exceptions to pass back to the caller - they should be used in exceptional cases.
If you do intend on using return codes, however, I would be more inclined to use enum's (though, again, it depends what the purpose of the code is). That way, it is easy for the caller to check against an available selection of return codes. Also, a comment on using integers or strings as error codes - it may not be very descriptive for a caller to know what the issue was. In this case, throwing an Exception or a specific type (containing the error message), or returning a pre-defined enum with a descriptive name, would be more meaningful to the caller.

From these short code snippets which does nothing it is very difficult to say what is best practice.
In general it is best to push exceptions to where they are handled best. If you are writing a framework for interfacing with some webservice the users of your framework will most likely not care about network exceptions etc. - they want return codes or, even better some framework specific exceptions that you include/code.

Hm - in your situation I'd rather do the following, but it really depends on the situation:
public string Method1()
{
string status = "0";
//Code - Exception may be thrown
return "0";
}
string status = "0";
ClassA ObjA = new ClassA();
try
{
status = objA.Method1();
}
Catch(Exception Ex)
{
//Log Exception EX
status = "-1;
}
EDIT
Sometimes it's hard to define values that indicate whether an error occurred in the method. You should keep Nullable types in mind. If you can find a suitable return value that indicates errors, it may also be ok to log the error within the method that caused the error and just react to the return value as you suggested.
By the way: In your code you're calling Method1 twice if the first call succeeded. I guess that is because it is a quick sample...

class MyException : Exception
{
public readonly int status;
public MyException(int status, string msg):base(msg)
{
this.status = status;
}
}
public string Method1()
{
throw new MyException(-1,"msg");
return "0";
}
SomeCode()
{
try
{
Method1();
}catch(MyException ex)
{
ex.status //here you get the status
}
}

Related

Correct way to pass errors back to the calling code

I have a function called connect like so:
public boolean connnect(){
{
..... connecting codde
if(connectionSuccessfull)
{
return true;
}
else
{
return false;
}
}
This is a very basic form of error handling, I want to upgrade this function to handle errors correctly. Such as not just tell me false there was an error, but be able to say, error, Authentication failed, or Time-out error etc.
This information then needs to be sent back up the line to the Caller so it can know what happened.
What is the correct way to go about doing this?
{EDIT}
In my care its quite probable that an exception will occur I would say 50% of the time.
I have come up with this, does it look partially correct?
namespace MobileWebServices.Exceptions
{
//Timeout
public abstract class TimeOutException : Exception
{
}
public class ConnectingTimeOutException : TimeoutException
{
}
public class DissconnectingTimeOutException : TimeoutException
{
}
//Authetntication
public abstract class AuthenticationException : Exception
{
}
public class BadAuthenticationException : AuthenticationException
{
}
}
Something along the lines of:
public void Connect()
{
try
{
//code here to look-up the connection details
if(!ValidateConnectionDetails(details))
throw new InvalidOperationException("The connection details are not valid.");
//code here to establish the connection
if(SomeTestThatShowsWereNotHappyWithTheConnection())
throw new Exception("The connection is bad, for some reason");
}
catch(SocketException se)
{
//We'd only have this block if a socket exception is possible. We might just allow it to pass on up.
throw; // User now gets the exception we got, exactly.
//We might re-throw the error, but from here so the stack-trace goes to here rather than the innards of this method:
throw se;
//Most usefully we might throw a new exception that contains this as an inner exception:
throw new Exception("Connecting failed", se);
//Or even better, we might throw a more well-defined exception, that relates to this operation more specifically, with or without the inner exception, depending on whether that is likely to be useful:
throw new ConnectionException("Some message, or maybe just a default is defined in the constructor");
//OR:
throw new ConnectionException("Some message, or maybe just a default is defined in the constructor", se);
}
catch(Exception ex)
{
//If we get to an exception ourselves that isn't of a particular type we're expecting, we probably shouldn't catch it at all. We might though want to note the exception before re-throwing it, or throw a more specific connection with this as an inner-exception:
Log(ex);
throw;
}
}
Because you're no longer returning a value to indicate success, you could also now return an object that represents the connection you created:
public ConnectionObject Connect()
{
// Much as above, but returning the object before the end of the `try`.
}
Returning values representing failure should only be done if that failure is both likely to happen, and something you expect the calling code to be able to reasonably react to right at the point of calling. This isn't that likely with code to connect since the calling code could be code that e.g. connects and then does an operation, and the code calling that in turn is where the exception (whether from here or the subsequent operation) should be caught - it's the code that ultimately cares about the failing.
In the latter case, then returning a value indicating the failure makes a lot more sense. Here though, I'd probably still consider an exception, because it can encapsulate more information, be used by coders in the normal way they use other .NET methods, and because the calling code is probably not written thinking "try to get the connection and then if it works..." it's written thinking "get the connection and then..." with the error case being exactly that; an error case. (For comparison, a method like int.TryParse() is to answer the question "does this string represent an integer, and if so what is it?" where the method int.Parse() answers the question "what is the integer in this string?" with there not being an integer being an error condition).
To think of it another way. Are you currently using a web-browser to browse the web, or are you using it to try to browse the web? Your internet connection could die on you, stopping you from continuing to read these answers, but you'd consider that a problem in what you were trying to do.
The normal approach is to throw an exception (perhaps of a user-defined type), and then to catch those exceptions at a higher level.
If for some reason you cannot use exceptions, you could instead write a wrapper class that encompassed an error message (which would be null if no error occurred) and the bool result (which would only be relevant if the error message is null).
However, I would recommend using exceptions. (The only issue might be whether or not you need to globalise the error message string in the exception, but the consensus is that you should not.)
Here is a sample on how things should be done :
First use your connect() method to return an object (like a Socket for example).
Return a null one if it fails connecting without throwing an Exception.
In your connect() method try/catch your connecting instructions, and rethrow those catched.
Then in the calling method, catch all the Exceptions that can be thrown, and check if the returned object is null or not.
Here is an example of code using Sockets :
public static Socket connect()
{
Socket s = null;
try
{
IPEndPoint iEP = new IPEndPoint("127.0.0.1", 8080);
s = new Socket(iEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
s.Connect(iEP);
if(!s.Connected)
{
return null;
}
}
catch(Exception e)
{
throw e;// Rethrow the Exception to the caller
}
return s;
}
public static void Main(String[] args)
{
Socket mySocket = null;
try
{
mySocket = connect();
}
catch(SocketException e)
{
// TODO - Detailed error about a SocketException
Console.Error.WriteLine("SocketException: " + e.Message + "(" + e.ErrorCode + ")");
}
catch(SecurityException e)
{
// TODO - Detailed error about a SecurityException
Console.Error.WriteLine("SecurityException: " + e.Message);
}
catch(Exception e)
{
// TODO - Detailed error about those Exceptions :
// ArgumentNullException, ObjectDisposedException and InvalidOperationException
Console.Error.WriteLine(e.GetType() + ": " + e.Message);
}
if(mySocket == null)
{
// TODO - Error while initializing the Socket
Console.Error.WriteLine("Error while initializing the Socket");
}
// TODO - Use your Socket here
}
I think the best way is using the try catch exception surrounding your call with the exception you want :
catch(TimeoutException ex)
{
//Do something
}
catch(SqlException ex)
{
//do something
}
//....
catch(Exception ex)
{
//do something
}
Make sure of the order of your catch ( the global Exception in last)

Catching Exception message from Boolean method

I have seen similar questions, but not exactly this:
I would like to know the right way of determining whether a method is executed correctly or not, returning a boolean, and if the method is not executed know the reason, even if an exception is thrown.
I do it in this way, but I think that return inside the catch is a bad practice, so which is the right way?:
if(!myObject.DoSomething('A', out result))
{
MessageBox.Show(myObject.ErrorMessage);
[...]
}else{
MessageBox.Show(result);
[...]
}
class myObject()
{
public string ErrorMessage;
bool DoSomething(char inputValue, out string result)
{
try
{
if(inputValue == 'A')
{
ErrorMessage = "Bad input value: " + inputValue;
return false;
}
[...]
return true;
}catch(Exception ex){
ErrorMessage = ex.Message;
return false;
}
}
I don't like trhow the exception inside the catch because I lose the control of the application (and I can't get the description), and the exception always finish in the form. And if I show the exception in the form, I don't need try catch in the rest of the classes.
I mean that try {} catch(Exception ex) { throw ex;} is the same as not putting try catch.
thanks a lot
My suggestion would be to create your own Exception type (possibly global), and pass it in as a reference.
Thereafter you can still get back your boolean indicating success or failure (and having only one return outside of the try..catch).
public class CustomException
{
private string _message;
private string _title;
public CustomException()
{
_title = "";
_message = "";
}
public CustomException(string title, string message)
{
_title = title;
_message = message;
}
}
Then call DoSomething passing in an instance of CustomException (ce in this case).
CustomException ce = new CustomException();
Be advised this is the best process to solve the problem of having to return a boolean indicating success or failure and know the message, for example; dumping it to a log file or logging to database (particularly for Service Calls - WCF)
However this is not a solution for bad logic in handling business process.
Return false inside a catch isn't by itself bad practice. It's useful when you handle a piece of code's exceptions and it must not fail.
For example, I'm working on a printer piloting DLL at the time, and this DLL must read a XML file containing multiple records to print. The method must not fail because one record fails to print, but it still can return exception if the XML file is not correctly formated.
public void Print(string xmlFile)
{
if (String.IsNullOrWhiteSpace(xmlFile))
throw new ArgumentNullException("No xml file has been passed to the Print method.");
// This line will most likely throw an exception if the XMl file is not well formated
XDocument dom = XDocument.Load(xmlFile);
foreach (XElement n in dom.XPathSelectElements("//RECORDS/RECORD"))
{
try
{
// send commands to the printer, if the printer fails to print, throw a PrinterRecordException
}
catch (PrinterRecordException e)
{
// log print failure, but keep on printing the rest
continue;
}
catch (Exception e)
{
// dunno what happened, but still have to print the rest
continue;
}
}
}
In this example, my function could return false instead of throwing exceptions to the main program, if this program doesn't care. In my case it does :p In my opinion, that's how you should think your method.
Exception handling methods and best practices are a some-what subjective matter. I cannot attest to the method I'm about to present because I have only just started to use it in my own project.
What I suggest is having a static ExceptionHandler class with which you can register any exception to be handled by Generic Parameter and its corresponding handler. This will decouple your business logic from your UI in case you wanted to display some kind of message box when a particular exception occurs.
Here's an example:
/// the real implementation uses lambda's and/or implementations of IExceptionHandler<TException>
ExceptionHandler.Register<InvalidPasswordException>(() => /*some handler logic*/);
// ... else where in the code ...
catch (InvalidPasswordException ex)
{
// do resource clean-up and raise exception for listeners such as the UI or logging infrastructure.
ExceptionHandler.Raise(ex);
}
So far this looks promising, especially when compared with my previous approaches. But only time will tell.
Update
The ExceptionHandler class itself need not be static, for example you might want to have different instances of ExceptionHandlers at different layers of your application if you are using a layered architecture.

When to Throw an Exception? When to Handle an Exception (Service Layer, Controller) where?

I rewritten my question as I think it was too wordy and maybe what I am trying to achieve was lost.
I written this code in notepad so it may have mistakes and some stuff maybe not well thoughout but it is to illustrate what I see my options are.
// I wrap all code send back from service layer to controller in this class.
public class ResponseResult
{
public ResponseResult()
{
Errors = new Dictionary<string, string>();
Status = new ResponseBase();
}
public void AddError(string key, string errorMessage)
{
if (!Errors.ContainsKey(key))
{
Errors.Add(key, errorMessage);
}
}
public bool IsValid()
{
if (Errors.Count > 0)
{
return false;
}
return true;
}
public Dictionary<string, string> Errors { get; private set; }
public ResponseBase Status { get; set; }
}
public class ResponseResult<T> : ResponseResult
{
public T Response { get; set; }
}
public class ResponseBase
{
public HttpStatusCode Code { get; set; }
public string Message { get; set; }
}
Option 1 (what I am using now)
//controller
public HttpResponseMessage GetVenue(int venueId)
{
if (venueId == 0)
{
ModelState.AddModelError("badVenueId", "venue id must be greater than 0");
if (ModelState.IsValid)
{
var venue = venueService.FindVenue(venueId);
return Request.CreateResponse<ResponseResult<Venue>>(venue.Status.Code, venue);
}
// a wrapper that I made to extract the model state and try to make all my request have same layout.
var responseResult = new ResponseResultWrapper();
responseResult.Status.Code = HttpStatusCode.BadRequest;
responseResult.Status.Message = GenericErrors.InvalidRequest;
responseResult.ModelStateToResponseResult(ModelState);
return Request.CreateResponse<ResponseResult>(responseResult.Status.Code, responseResult);
}
// service layer
public ResponseResult<Venue> FindVenue(int venueId)
{
ResponseResult<Venue> responseResult = new ResponseResult<Venue>();
try
{
// I know this check was done in the controller but pretend this is some more advanced business logic validation.
if(venueId == 0)
{
// this is like Model State Error in MVC and mostly likely would with some sort of field.
responseResult.Errors.Add("badVenueId", "venue id must be greater than 0");
responseResult.Status.Code = HttpStatusCode.BadRequest;
}
var venue = context.Venues.Where(x => x.Id == venueId).FirstOrDefault();
if(venue == null)
{
var foundVenue = thirdPartyService.GetVenue(venueId);
if(foundVenue == null)
{
responseResult.Status.Code = HttpStatusCode.NotFound;
responseResult.Status.Message = "Oops could not find Venue";
return responseResult;
}
else
{
var city = cityService.FindCity(foundVenue.CityName);
if(city == null)
{
city = cityService.CreateCity(foundVenue.CityName);
if(city.Response == null)
{
responseResult.Status.Code = city.Status.Code;
responseResult.Status.Message = city.Status.Message;
return responseResult;
}
CreateVenue(VenueId, city.Response, foundVenue.Name);
responseResult.Status.Code = HttpStatusCode.Ok;
// I don't think I would return a success message here as the venue being displayed back to the user should be good enough.
responseResult.Status.Message = "";
reponseResult.Response = foundVenue;
}
}
return responseResult;
}
}
catch (SqlException ex)
{
ErrorSignal.FromCurrentContext().Raise(ex);
responseResult.Status.Code = HttpStatusCode.InternalServerError;
responseResult.Status.Message = GenericErrors.InternalError;
// maybe roll back statement here depending on the method and what it is doing.
}
// should I catch this, I know it should be if you handle it but you don't want nasty messages going back to the user.
catch (InvalidOperationException ex)
{
ErrorSignal.FromCurrentContext().Raise(ex);
responseResult.Status.Code = HttpStatusCode.InternalServerError;
responseResult.Status.Message = GenericErrors.InternalError;
}
// should I catch this, I know it should be if you handle it but you don't want nasty messages going back to the user.
catch (Exception ex)
{
ErrorSignal.FromCurrentContext().Raise(ex);
responseResult.Status.Code = HttpStatusCode.InternalServerError;
responseResult.Status.Message = GenericErrors.InternalError;
}
return responseResult;
}
// another service layer.
// it is ResponseResult<City> and not city because I could have a controller method that directly calls this method.
// but I also have a case where my other method in another service needs this as well.
public ResponseResult<City> CreateCity(string CityName)
{
ResponseResult<City> responseResult = new ResponseResult<City>();
try
{
City newCity = new City { Name = "N" };
context.Cities.Add(newCity);
context.SaveChanges();
responseResult.Status.Code = HttpStatusCode.Ok;
responseResult.Status.Message = "City was succesfully added";
}
// same catch statmens like above
catch (SqlException ex)
{
ErrorSignal.FromCurrentContext().Raise(ex);
responseResult.Status.Code = HttpStatusCode.InternalServerError;
responseResult.Status.Message = GenericErrors.InternalError;
// maybe roll back statement here depending on the method and what it is doing.
}
return responseResult;
}
As you can see the methods are all wrapped in the status codes as they could be directly called by the controller being public. FindCity() and CreateVenue() could also have this wrapping.
Option 2
public HttpResponseMessage GetVenue(int venueId)
{
try
{
if (venueId == 0)
{
ModelState.AddModelError("badVenueId", "venue id must be greater than 0");
if (ModelState.IsValid)
{
var venue = venueService.FindVenue(venueId);
return Request.CreateResponse<ResponseResult<Venue>>(HttpSatusCode.Ok, venue);
}
// a wrapper that I made to extract the model state and try to make all my request have same layout.
var responseResult = new ResponseResultWrapper();
responseResult.Status.Code = HttpStatusCode.BadRequest;
responseResult.Status.Message = GenericErrors.InvalidRequest;
responseResult.ModelStateToResponseResult(ModelState);
return Request.CreateResponse<ResponseResult>(responseResult.Status.Code, responseResult);
}
catchcatch (SqlException ex)
{
// can't remember how write this and too tried to look up.
return Request.CreateResponse(HttpStatusCode.InternalServerError;, "something here");
}
}
public Venue FindVenue(int venueId)
{
try
{
// how to pass back business logic error now without my wrapper?
if(venueId == 0)
{
// what here?
}
var venue = context.Venues.Where(x => x.Id == venueId).FirstOrDefault();
if(venue == null)
{
var foundVenue = thirdPartyService.GetVenue(venueId);
if(foundVenue == null)
{
// what here?
}
else
{
var city = cityService.FindCity(foundVenue.CityName);
if(city == null)
{
city = cityService.CreateCity(foundVenue.CityName);
if(city == null)
{
// what here?
}
CreateVenue(VenueId, city.Response, foundVenue.Name);
}
}
return venue;
}
}
catch (SqlException ex)
{
// should there be a try catch here now?
// I am guessing I am going to need to have this here if I need to do a rollback and can't do it in the controller
// throw exception here. Maybe this won't exist if no rollback is needed.
}
return null;
}
public City CreateCity(string CityName)
{
// if it crashes something I guess will catch it. Don't think I need to rollback here as only one statement being sent to database.
City newCity = new City { Name = "N" };
context.Cities.Add(newCity);
context.SaveChanges();
return newCity;
}
As you see with option 2, I might still need to wrap it in try catches for rollbacks and I am not sure how to handle advanced business validation.
Also with catching everything in the controller and sending back vanilla objects(without my wrapper) I am unsure how to do fine grain HttpStatus codes(say like notFound,Create and such)
Sorry for the brief response, but here is my general rule - if an exception occurs which you expect might happen, deal with it - either by retrying or telling the user something went wrong and giving them options to fix it.
If an unexpected exception occurs, if it's something you can deal with (e.g a timeout which you can retry) try to deal with it, otherwise get out - just think what any MS app does - e.g. office - you get an apology that something went wrong and the app ends. It's better to end gracefully than to potentially corrupt data and leave things in a real mess.
This is an article with Java-specific concepts and examples, but the broad principles here are the way to go.
Distinguish between fault exceptions, which are catastrophic and unrecoverable, and contingency exceptions, which are very much recoverable. Let the faults "bubble" to the fault barrier, where you handle appropriately. For example, you might log the error, E-mail someone or send a message to a message queue, and present the user with a nice, informative error page.
Whatever you do, be sure to preserve all the exception information from the source.
Hope that helps.
Throw an exception wherever your code determines that something has gone wrong.
You always need to handle exceptions in methods which are called directly by the end-user. This is to cater for unexpected errors which your code doesn't have specific handling for. Your generic handling code would typically log the error and may or may not include letting the user know that an unexpected error has occurred.
But if there are errors which you can expect ahead of time, you'll often want to handle these lower down in the code, nearer to the point at which they occur, so that your application can "recover" from the error and continue.
I think exceptions are useful any time you need to return details of a failure from a method, whilst being able to use the ideal return type for the method you're calling.
You said in your question:
Now for me I try to return error messages back to the the controller
and try not to really catch anything in the controller.
If the service method is supposed to ideally return a Venue object, how do you return this potential error message back to the controller? an out parameter? change the return type to something which has an error message property on it?
If you're doing either of those options, I think you're reinventing the wheel... i.e. creating a way to return exception information when one already exists.
Finally, Exceptions are strongly typed representations of what went wrong. If you return an error message, then that is fine to send back to the user, but if you need to programatically do different things based on the details of the error, then you don't want to be switching on magic string.
For example, wouldn't it be handy to differentiate between authorization errors and not found errors so you can return the most appropriate http status code to the user?
Don't forget that the Exception class has a Message property you can simply return to the user if you want to use it that way
To make sure I understand the question, your are creating a web service and want to know when to handle and when to throw exceptions.
In this situation I would strongly recommend that you catch all exceptions. "Unhandled" exceptions are very bad form. On web sites they result in displays that range from meaningless to dangerous by exposing internal information that you do no want the public to see.
If this is a good sized program I suggest that you create your own MyException class which derives from System.Exception. The purpose of this is provide a place for you to add additional information specific to your application. Here are some typical things I like to add to my MyException classes:
An ID number that will help me find the location in the code where the problem occurred.
A "LogMessage" method that logs the exception, sometimes to the Windows Event Log. Whether or not you log and to which log you write depends on what you want recorded, and the severity of the situation.
An indicator that shows the exception has been logged so the above method will not log twice even if it gets called more than once.
Anything else that might be useful given the circumstance.
I also like to put the text of the messages in an external resource file, like an XML document, and key them to the error number that you assign. This allows you to change the error text to improve clarity without having to redeploy the application.
Catch all exceptions and create a new instance of your MyException type and put the original exception into inner exception property. Below the first level of my application, I always throw one of my MyException instances rather than the original exception.
At the top level (application level), NEVER let an exception go unhandled and never throw your own exception. A better way is to return an error code and message in your data contract. That way the client application will only get what you want them to see. The only exceptions they'll need to worry about are the ones outside your scope, i.e. configuration errors or communication failures. In other words if they are able to invoke your service and the network stays connected you should give them a response they can interpret.
Hope this helps.
PS I didn't include a sample exception as I am sure a little searching will find many. Post if you want me to put up a simple sample.
Use try catch at all levels and bubble it up. Optionally, log the error in a file or database. I use text file - tab delimited. Capture at each level
1. Module Name (Use C# supplied methods to get this)
2. Method Name
3. Code Being Executed (User created - "Connecting to database")
4. Error Number
5. Error Description
6. Code Being Executed (User created - "Accessing database")
7. Error Number for the end user
8. Error Description for the end user
Additionally, I also pass a unique identifier like - Session Id in case of Web, Logged in User Id, User Name (if available)
I always have the Exception catch block. In here I set the error number as -0 and the message from the exception object as the error description. If it is SQL Server related - I capture SQL Exception. This generates an error number - I use that.
I want to extend this some more though.

C# try catch continue execution

I have a question that might seem fairly simple (of course if you know the answer).
A certain function I have calls another function but I want to continue execution from the caller even though the callee has thrown an exception. Let me give you an example:
something function1()
{
try
{
//some code
int idNumber = function2();
//other code that need to execute even if function2 fails
return something;
}
catch(Exception e)
{//... perhaps something here}
}
EDIT: function1 also has a return statement so nothing can in fact crash on the way
In function2 I need to do stuff but I only need to log if anything fails, example:
int function2()
{
try
{
//dostuff
}
catch(Exception e)
{
//Log stuff to db
}
}
ok, now my question is, what should I do if I wanted to continue execution in function1 even if function 2 throws an error?
Sometimes I mix up if I should do throw; or throw e; or throw nothing at all (leave catch block empty)
Leaving the catch block empty should do the trick. This is almost always a bad idea, though. On one hand, there's a performance penalty, and on the other (and this is more important), you always want to know when there's an error.
I would guess that the "callee" function failing, in your case, is actually not necessarily an "error," so to speak. That is, it is expected for it to fail sometimes. If this is the case, there is almost always a better way to handle it than using exceptions.
There are, if you'll pardon the pun, exceptions to the "rule", though. For example, if function2 were to call a web service whose results aren't really necessary for your page, this kind of pattern might be ok. Although, in almost 100% of cases, you should at least be logging it somewhere. In this scenario I'd log it in a finally block and report whether or not the service returned. Remember that data like that which may not be valuable to you now can become valuable later!
Last edit (probably):
In a comment I suggested you put the try/catch inside function2. Just thought I would elaborate. Function2 would look like this:
public Something? function2()
{
try
{
//all of your function goes here
return anActualObjectOfTypeSomething;
}
catch(Exception ex)
{
//logging goes here
return null;
}
}
That way, since you use a nullable return type, returning null doesn't hurt you.
Why cant you use the finally block?
Like
try {
} catch (Exception e) {
// THIS WILL EXECUTE IF THERE IS AN EXCEPTION IS THROWN IN THE TRY BLOCK
} finally {
// THIS WILL EXECUTE IRRESPECTIVE OF WHETHER AN EXCEPTION IS THROWN WITHIN THE TRY CATCH OR NOT
}
EDIT after question amended:
You can do:
int? returnFromFunction2 = null;
try {
returnFromFunction2 = function2();
return returnFromFunction2.value;
} catch (Exception e) {
// THIS WILL EXECUTE IF THERE IS AN EXCEPTION IS THROWN IN THE TRY BLOCK
} finally {
if (returnFromFunction2.HasValue) { // do something with value }
// THIS WILL EXECUTE IRRESPECTIVE OF WHETHER AN EXCEPTION IS THROWN WITHIN THE TRY CATCH OR NOT
}
Or you can encapsulate the looping logic itself in a try catch e.g.
for(int i = function2(); i < 100 /*where 100 is the end or another function call to get the end*/; i = function2()){
try{
//ToDo
}
catch { continue; }
}
Or...
try{
for(int i = function2(); ; ;) {
try { i = function2(); return; }
finally { /*decide to break or not :P*/continue; } }
} catch { /*failed on first try*/ } finally{ /*afterwardz*/ }
just do this
try
{
//some code
try
{
int idNumber = function2();
}
finally
{
do stuff here....
}
}
catch(Exception e)
{//... perhaps something here}
For all intents and purposes the finally block will always execute. Now there are a couple of exceptions where it won't actually execute: task killing the program, and there is a fast fail security exception which kills the application instantly. Other than that, an exception will be thrown in function 2, the finally block will execute the needed code and then catch the exception in the outer catch block.
Do you mean you want to execute code in function1 regardless of whether function2 threw an exception or not? Have you looked at the finally-block? http://msdn.microsoft.com/en-us/library/zwc8s4fz.aspx
In your second function remove the e variable in the catch block then add throw.
This will carry over the generated exception the the final function and output it.
Its very common when you dont want your business logic code to throw exception but your UI.

Additional try statement in catch statement - code smell?

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.

Categories

Resources