I would like to know which is the best way to make a Exception treatment, because inside my Try statement, I have a lot of validations, and if I get some Exception there, my Catch statement can tell me what happens, but how could I know in which field occurs the Exception ?
Sample Code
try
{
// If I get a Exception when converting to number,
// I will understand the error
// but how could I know where in my `Try` statement was the error ?
int valor = Convert.ToInt32(xmlnode[i].ChildNodes.Item(2).InnerText.Trim());
// A Lot of another validations here
}
Catch(Exception e)
{
this.LogInformation(e.Message);
}
Best practises would be not to use Try-Catch at all when you convert strings to numbers. Therefore you should use the TryParse methods like int.TryParse.
// note that here is also a possible error-source
string valorToken = xmlnode[i].ChildNodes.Item(2).InnerText.Trim();
int valor;
if(!int.TryParse(valorToken, out valor))
{
// log this
}
// else valor was parsed correctly
Apart from that, if you want to provide exact error messages you have to use multiple try-catch or handle different exception types (the most general Exception type must be the last).
Don't use Convert.ToInt32 if you're unsure of the value. Use Int32.TryParse instead:
int valor;
if (Int32.TryParse(xmlnode[i].ChildNodes.Item(2).InnerText.Trim(), out valor))
{
// Worked! valor contains value
}
else
{
// Not a valid Int32
}
In addition you should not be using Exceptions to catch validation errors. Your validation code should calculate if the value is correct, rather than failing when it isn't. A validation class should expect to receive both valid and invalid data as input. Because you expect invalid input you should not be catching exceptions when it's invalid.
Come up with a test that checks if the data is valid and return true or false. Pretty much all numeric types have a TryParse method like the above. For your custom rules for other validation methods come up with a specification that defines exactly what valid and invalid input is and then write a method to implement that specification.
Move try..catch inside loop. Thus you will know which item exactly caused exception
foreach(var xmlNode in nodes)
{
try
{
//
int valor = Convert.ToInt32(xmlNode.ChildNodes.Item(2).InnerText.Trim());
// A Lot of another validations here
}
catch(Exception e)
{
LogInformation(e.Message); // current item is xmlNode
return;
}
}
If there is even the remotest possibility that the value you're tring to parse will not be parsable, it is therefore not an exceptional circumstance, vis. should not be treated as an exception.
In this case, there is TryParse, which allows you to determine that the value is not valid for parsing:
int valor;
if(int.TryParse(xmlnode[i].ChildNodes.Item(2).InnerText.Trim(), out valor))
{
// "valor" is sucessfully parsed
}
else
{
// invalid parse - do something with that knowledge
}
Unless its different Exceptions that get created (i.e. different classes) then you will need to handle this with different try catches.
Typically you can do:
try
{
// If I get a Exception when converting to number,
// I will understand the error
// but how could I know where in my `Try` statement was the error ?
int valor = Convert.ToInt32(xmlnode[i].ChildNodes.Item(2).InnerText.Trim());
// A Lot of another validations here
}
Catch(IOException ioe) {
// Handle, log
}
Catch(ArgumentNullException ane) {
// Handle, log
}
Catch(Exception e)
{
// Handle, log and potentially rethrow
}
You could also have individual try catches (which is kind of what most people would do I think) or nested try catches in your try block:
Like
// First block
try {
// Convert here once
} catch (Exception ex) {
// Handle and log
}
// Second block
try {
// Convert here once
} catch (Exception ex) {
// Handle and log
}
Not sure if that helps at all.
try
{
}
catch (Exception ex)
{
var stackTrace = new StackTrace(ex, true);
var frame = stackTrace.GetFrame(0);
var line = frame.GetFileLineNumber();
var method = frame.GetMethod();
}
Related
How to check if a function throws an exception in c#?
public List<string> GetFileNames()
{
try
{
// do something
// return something
}
catch(Exception ex)
{
// do something
// log something
}
}
then i will call GetFileNames() somewhere in my code, but I want to check if it throws an exception,
like,
var list = GetFileNames(); // can be 0 count
if(GetFileNames() throws an error)
{
DoThisMethod()
}
else
{
DoThisOtherMethod();
}
You have a lot of options here:
This is generally done with a Try... pattern like TryParse.
bool TryGetFileNames(out List<string> fileNames)
You can also return null.
You can"t do this in c#.
The closest thing to what you are describing is the "checked exceptions" which are implemented in java. In such case the function will declare it is throwing some exception like so :
public void foo() throws IOException {
// your code
}
At compile time you will be forsed to take care of this by either enclosing this in TryCatch block or propagate this the same way in your function.
In c# enclose the function in TryCatch block and use different function in case of faliure.
The fundamental problem is that you're attempting to handle an exception when you're not able to do so.
If GetFilenames cannot recover from the exception, it should throw an exception itself. That may be by omitting a try/catch entirely, or by catching it, wrapping and re-throwing.
public List<string> GetFilenames() {
try {
...
} catch (Exception e) {
throw new FileLoadException("Failed to get filenames", e);
// Or if you don't want to create custom exceptions, perhaps use an InvalidOperationException
}
}
Failing that, if you don't actually need to abstract the functionality, don't catch the exception in GetFilenames at all, then call it like this:
try {
var list = GetFilenames()
DoSomething();
} catch (Exception e) {
DoSomethingElse();
}
I think you can make it simpler:
public void ICallGetFileNames()
{
var list = new List<YourObject>();
try
{
list = GetFileNames();
DoThisOtherMethod();
}
catch (Exception ex)
{
DoThisMethod();
}
}
This way, if the exception is thrown by your GetFileNames method, the DoThisOtherMethod() won't be called, since your code is going directly to the Exception block. Otherwise, if no exception is thrown, your code will call the DoThisOtherMethod just after the GetFileNames method.
I have the following situation in code, whats the best way to manage it, the comments contains the situations, and please recommend the best practice.
try
{
string errorMessage = AccountClient.GetAccount(id, out accountDetails);
// FIRST WAY : REMOVE THIS NULL CHECK AT ALL AND LEAVE GetAccountDetails to control
// the Null situation?
if (accountDetails == null)
{
// Second Way: This way? Throw exception here?
throw new ArgumentNullException(nameof(accountDetails));
//Third way? break the function?
break;
}
// GetAccount Details already has null control
Subscription subscription = AccountProcessor.GetAccountDetails(accountDetails);
}
catch (Exception e)
{
throw;
}
First of all, the costruction
catch (Exception e) {
throw;
}
is redundant one and can be eliminated. Now about nulls. There're two
cases:
null is an erroneous value and so it should be signalled
null is an expected, ordinary value and thus it should be proceeded
And so you have (null is an error)
string errorMessage = AccountClient.GetAccount(id, out accountDetails);
// What's wrong: it's id which doesn't correspond to any detail
// (we expect id being s.t. AccountClient.GetAccount(id...) returns not null detail)
if (accountDetails == null)
throw new ArgumentException($"Incorrect id {id} which doesn't have any detail.",
nameof(id));
Subscription subscription = AccountProcessor.GetAccountDetails(accountDetails);
Or (null is an expected outcome)
string errorMessage = AccountClient.GetAccount(id, out accountDetails);
if (accountDetails == null)
return null; // or any reasonable value, or just return, or create new Subscription
Subscription subscription = AccountProcessor.GetAccountDetails(accountDetails);
If you can do anything about null input then handle it.
try
{
string errorMessage = AccountClient.GetAccount(id, out accountDetails);
if (accountDetails == null)
{
// do something about it. Maybe write some logs, substitute with a default value
// or throw appropriate exception ...
}
Subscription subscription = AccountProcessor.GetAccountDetails(accountDetails);
}
catch (Exception e)
{
throw;
}
if you can't then let GetAccountDetails decide what should happen.
try
{
string errorMessage = AccountClient.GetAccount(id, out accountDetails);
Subscription subscription = AccountProcessor.GetAccountDetails(accountDetails);
}
catch (Exception e)
{
throw;
}
Also there is no need to catch an exception, doing nothing and then throw it so you can remove the whole try catch block.
It depends on where this ID is coming from. If the user typed the ID, then I wouldn't generate an Exception, since it is not a error in your program. Just treat the user input and show a proper message. Exceptions are costly, so I usually use them only when i have a real programa failure. Besides that, if you write a custom Exception Handler, it wouldn`t make sense to log a error caused by wrong user input. So i would make it like this:
if (AccountClient.AccountExists(id))
{
AccountDetails details = AccountClient.GetAccount(id);
Subscription subscription = AccountProcessor.GetAccountDetails(accountDetails);
}
Anyway, its good to treat the input on the same way, even if you had treated like above, in case there is any other non treated call to it:
public AccountDetails GetAccount(int id)
{
if (Exists(id))
GetTheAccount(id);
else
throw new Exception(String.Format("Account {0} doesn't exists", id));
}
In this case I would use an Exception because it could really represent an error, if the caller function is passing a wrong value, for instance.
so currently i am writing a program something like this:
try
{
mainprocessing();
}
catch (exception e)
{
//first catch block.
//do something here
}
mainprocessing()
{
try
{
string value = ReadCell.ReadCellValue(allEmployeeTimesheet[i], "Sheet1", "A1"); //I am calling ReadCellValue() method to check the value of A1 cell of an excel spreadsheet and if it is null, it will be handled in the following catch block.
}
catch (NullReferenceException e)
{
//second catch block
//something here to handle it
}
}
But when I run the program now, if string value is null, the exception will be handled in the first catch block. However I want it to be handled in the second catch block. Is there any way to manipulate this?
Didn't read the question the proper way, was thinking you want to get explicit into the top level exception.
When a value is null and trying to access this variable, there will be no reference to an actual object and so an NullReferenceException will be thrown but in this case you are allocating value to an reference so there is another exception thrown rather than NullReferenceException.
The only way to found out which Exception is been thrown, add another catch block below the NullReferenceException.
catch (NullReferenceException e)
{
//second catch block
//something here to handle it, LOG IT!
}
catch (Exception exception)
{
Type exceptionType = exception.GetType();
}
When an Exception has been handled(catched) by the program it returns to the point where this function has been invoked, in this case 'mainprocessing'.
If you explicit WANT to get into the most top level Exception handling block, just throw a new Exception inside the catch, like this:
mainprocessing()
{
try
{
string value = ReadCell.ReadCellValue(allEmployeeTimesheet[i], "Sheet1", "A1"); //I am calling ReadCellValue() method to check the value of A1 cell of an excel spreadsheet and if it is null, it will be handled in the following catch block.
}
catch (NullReferenceException e)
{
//second catch block
//something here to handle it, LOG IT!
throw new Exception("top level exception");
}
}
As mentioned in the comments handling exceptions is not the way to handle flow control in C#. You use them if something unexpected happens, something you are not able to check in advance, before starting your process (e.g. file is corrupted and your read is aborted unexpectedly).
In your case just go with simple if check:
string value = ReadCell.ReadCellValue(allEmployeeTimesheet[i], "Sheet1", "A1");
if (string.IsNullOrWhiteSpace(value))
{
// Handle the null/empty string here.
// From what you said probably the logic you wanted to use in your second catch block.
}
EDIT:
To handle the exception on the level of ReadCell just check if it's null before accessing the value. Then you have a couple of options. You can abort the execution (return) or try to get an instance of ReadCell.
if (ReadCell == null)
{
// abort the execution, create
}
string value = ReadCell.ReadCellValue(allEmployeeTimesheet[i], "Sheet1", "A1");
Alternatively just indent several ifs:
if (ReadCell != null)
{
string value = ReadCell.ReadCellValue(allEmployeeTimesheet[i], "Sheet1", "A1");
if (string.IsNullOrWhiteSpace(value))
{
// Handle the null/empty string here.
// From what you said probably the logic you wanted to use in your second catch block.
}
}
else
{
// Handle null case for ReadCell.
}
Here's how you should handle exceptions in your specific scenario:
private void btnDataStuff_Click(object sender, EventArgs e)
{
try
{
ProcessSomeData();
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex.Message);
MessageBox.Show("Inner exception: " + ex.InnerException.Message);
}
}
private void ProcessSomeData()
{
try
{
// Code where NullReferenceException exception happens
}
catch (NullReferenceException ex)
{
throw new ApplicationException("Data is null!!!", ex);
}
}
This is the proper way to handle and propagate your exceptions. I think this is what you originally wanted to accomplish. If NullReferenceException exception happens in the ProcessSomeData method - it will be propagated as a new exception with Data is null!!! message but it will also keep the original exception because it stores critical information for later debugging (call stack among other things). This way, you can have "nice" error messages in your application for the end user and original exceptions for the programmer to debug if needed.
This is a very simple example though. Please read this to learn best practices when handling exceptions. It's one of the most important aspects of programming that you will (have to) learn - you will eventuall learn it either way but why take the hard path when you can make your life easier from the start.
Also read up on C# coding conventions so you can write quality code from the start.
Other posters hinted that you should validate your data for null instead of catching exceptions and in most cases this is true but in case you still do want to catch some specific exceptions you now know a proper way to do so.
Hi I wanted to ask because I'm not sure if is it propriete using of Exception:
public int Method(int a, int b) {
if(a<b) throw new ArgumentException("the first argument cannot be less than the second");
//do stuff...
}
can I throw Exception after if statement? or should I always use try - catch when it goes with the exceptions?
That is perfectly valid. That is exactly what exceptions are used for, to check for "Exceptions" in your logic, things that weren't suppose to be.
The idea behind catching an exception is that when you pass data somewhere and process it, you might not always know if the result will be valid, that is when you want to catch.
Regarding your method, you don't want to catch inside Method but infact when you call it, here's an example:
try
{
var a = 10;
var b = 100;
var result = Method(a, b);
}
catch(ArgumentException ex)
{
// Report this back to the user interface in a nice way
}
In the above case, a is less than b so you can except to get an exception here, and you can handle it accordingly.
In this case, you don't want to catch the exception. You're throwing it to alert the caller that they've made a mistake in the way they called your method. Catching it yourself would prevent that from happening. So yes, your code looks fine.
That's perfectly fine. You're throwing the exception, not catching/handling it, so you wouldn't need a try/catch block for it.
This is perfectly valid, you can use the same construct even with the constructors.
But What you should not do is
public int Method(int a, int b)
{
try
{
if (a < b)
throw new ArgumentException("the first argument cannot be less than the second");
}
catch (Exception)
{
}
return 0;
}
You've got the right idea. You could use your code like this:
void MyMainMethod()
{
// ... oh, let's call my Method with some arguments
// I'm not sure if it'll work, so best to wrap it in a try catch
try
{
Method(-100, 500);
}
catch (ArgumentException ex)
{
Console.WriteLine(ex.Message);
}
}
public int Method(int a, int b)
{
if (a < b) throw new ArgumentException("the first argument cannot be less than the second");
//do stuff ... and return
}
It might help to look through MSDN's Handling and Throwing Exceptions and Best Practices for Handling Exceptions
What you've done here is perfectly Ok.
A common pattern for arg checks is to wrap the check/throw code in a static "Contract" class ensuring you have a consistent approach to exception management when validating input arguments.
Slightly off topic but if using .NET 4.0 you can also look at the new Code Contracts feature for validation of method input and output.
All above answers are correct but I like to mention one additional point here which I did not see mentioned in any of the answers. The reason why you should throw an exception and not return an integer e.g. 0 or -1 for signalling that an error occurred, is that the returned integer can be mistakenly treated/assumed as a valid result of your method. It is an integer anyway, and your method, after performing its internal logic returns an integer. So the caller of this method can mistakenly treat any returned integer as a valid result, which can lead to bugs down the line. In that case, throwing an exception makes perfect sense.
In Python, there is this useful exception handling code:
try:
# Code that could raise an exception
except Exception:
# Exception handling
else:
# Code to execute if the try block DID NOT fail
I think it's useful to be able to separate the code that could raise and exception from your normal code. In Python, this was possible as shown above, however I can't find anything like it in C#.
Assuming the feature or one like it doesn't exist, is it standard practice to put normal code in the try block or after the catch block?
The reason I ask is because I have the following code:
if (!IsReadOnly)
{
T newobj;
try
{
newobj = DataPortal.Update<T>(this);
List<string> keys = new List<string>(BasicProperties.Keys);
foreach (string key in keys)
{
BasicProperties[key] = newobj.BasicProperties[key];
}
}
catch (DataPortalException)
{
// TODO: Implement DataPortal.Update<T>() recovery mechanism
}
}
Which requires the normal code to be in the try block because otherwise if an exception was raised and subsequently handled, newobj would be unassigned, but it feels quite unnatural to have this much code in the try block which is unrelated to the DataPortalException. What to do?
Thanks
I would prefer to see the rest of the code outside the try/catch so it is clear where the exception you are trying to catch is coming from and that you don't accidentally catch an exception that you weren't trying to catch.
I think the closest equivalent to the Python try/catch/else is to use a local boolean variable to remember whether or not an exception was thrown.
bool success;
try
{
foo();
success = true;
}
catch (MyException)
{
recover();
success = false;
}
if (success)
{
bar();
}
But if you are doing this, I'd ask why you don't either fully recover from the exception so that you can continue as if there had been success, or else fully abort by returning an error code or even just letting the exception propagate to the caller.
Barbaric solution: create an Else class derived from Exception, throw an instance of it at the end of the try block, and use catch (Else) {...} to handle the other stuff.
I feel so dirty.
This will might get downvoted but doesn't c# have goto(note I have almost no c# knowledge so I have no idea if this works).
what about something like
try
{
...
}
catch(Exception ex)
{
...
goto Jump_past_tryelse
}
...//Code to execute if the try block DID NOT fail
Jump_past_tryelse:
...
C# does not have such a concept, so you are just left with three options,
put the else code inside the try.
put the else code outside the try catch block, use a local variable to indicate success or failure, and an if block around your else code.
put the else code in the finally block, use a local variable to indicate success or failure, and an if block arount you else code.
Allow me to repeat an idea from a similar StackOverflow question. You cannot do this directly, but you can write a method that encapsulates the behavior you need. Look at the original question to see how to implement the method (if you're not familiar with lambda expressions and Func delegates). The usage could look like this:
TryExceptRaise(() => {
// code that can throw exception
}, (Exception e) => {
// code to run in case of an exception
return (...);
}, () => {
// code to run if there is no exception
return (...);
});
Just put your "else" block before the catch. Then, it will only execute if code execution reaches that point:
try
{
fee();
fi();
foe();
fum();
/// put your "else" stuff here.
/// It will only be executed if fee-fi-foe-fum did not fail.
}
catch(Exception e)
{
// handle exception
}
Given that, I fail to see the use of try..catch...else unless there's something vital missing from the OP's description.
With C# version 7, you could use local functions to emulate this behaviour:
Example 1: (since C# version 7)
void Main()
{
void checkedCode()
{
try
{
foo();
}
catch (Exception ex)
{
recover();
return;
}
// ElseCode here
}
checkedCode();
}
If you prefer lambda syntax, you could also declare a run method
void Run(Action r) { r(); }
which only needs to be there once in your code, and then use the pattern for anonymous methods as follows
Example 2: (older C# versions and C# version 7)
Run(() => {
try
{
foo();
}
catch (Exception)
{
recover();
return;
}
// ElseCode here
});
whereever you need to enclose code in a safe context.
Try it in DotNetFiddle
Notes:
In both examples a function context is created so that we can use return; to exit on error.
You can find a similar pattern like the one used in Example 2 in JavaScript: Self-invoking anonymous functions (e.g. JQuery uses them). Because in C# you cannot self-invoke, the helper method Run is used.
Since Run does not have to be a local function, Example 2 works with older C# versions as well
You could do something like this:
if (!IsReadOnly)
{
T newobj = null;
try
{
newobj = DataPortal.Update<T>(this);
}
catch (DataPortalException)
{
// TODO: Implement DataPortal.Update<T>() recovery mechanism
}
if (newobj != null)
{
List<string> keys = new List<string>(BasicProperties.Keys);
foreach (string key in keys)
{
BasicProperties[key] = newobj.BasicProperties[key];
}
}
}
that would be the empty statement like hits
try
{
somethingThatCanThrow();
}
catch(Exception ex)
{
LogException(ex);
return;
}
ContinueFlow();
if (!IsReadOnly)
{
T newobj;
bool Done;
try
{
newobj = DataPortal.Update<T>(this);
List<string> keys = new List<string>(BasicProperties.Keys);
foreach (string key in keys)
{
BasicProperties[key] = newobj.BasicProperties[key];
}
Done = true;
}
catch (DataPortalException)
{
// TODO: Implement DataPortal.Update<T>() recovery mechanism
Done = false;
}
finally
{
if (newobj != null && Done == false)
{
List<string> keys = new List<string>(BasicProperties.Keys);
foreach (string key in keys)
{
BasicProperties[key] = newobj.BasicProperties[key];
}
}
}
}