Which exception would I use in a try/catch to find out when the user has inputted data in the wrong format?
Example:
try
{
string s = textBox1.Text;
// User inputs an int
// Input error
MessageBox.Show(s);
}
catch(what exception)
{
MessageBox.Show("Input in wrong format");
}
Thanks
Don't do this. It's a misuse of exception handling. What you are attempting to do is considered coding by exception, which is an anti-pattern.
An exception is exactly what it sounds like, an exception to the norm. It's defined by something you either haven't accounted for, or simply can't account for through traditional validation. In this situation, you can definitely account for a format issue ahead of time. If you know there is a possiblity that the inputted data will be in the wrong format, check for this case first. e.g.
if(!ValidateText(textBox1.text)) // Fake validation method, you'd create.
{
// The input is wrong.
}
else
{
// Normally process.
}
You should avoid using Exceptions as flow control.
If you want a textbox to be an int, this is where int.TryParse() method comes in handy
int userInt;
if(!TryParse(textBox1.Text, out userInt)
{
MessageBox.Show("Input in wrong format");
}
You can go with Exception ex to catch all exceptions. If you want to catch a more specific one, though, you'll need to look at the documentation for whatever functions you are using to check the validity of the input. For example, of you use int.TryParse(), then you will want to catch FormatException among others (see: http://msdn.microsoft.com/en-us/library/b3h1hf19.aspx for more information).
You can create your own exception like ↓
public class FormatException : Exception
And In your source , it might be...
if (not int) throw new FormatException ("this is a int");
Then , In your catch ...
catch(FormatException fex)
Related
I'm having a problem specifying the proper return value in a try/catch block.
I'm novice level scripter and have never used generics before.
The error message is:
"An object of type convertible to T is required"
What specifically do I need to return at the end of my try/catch?
private static T LoadData<T>(string filePath)
{
try
{
return JsonUtility.FromJson<T>(File.ReadAllText(filePath));
}
catch(Exception e)
{
// Something went wrong, so lets get information about it.
Debug.Log(e.ToString());
return ?????;
}
}
It really depends on the application behaviour that you want to define. You can have it return a new T() / default (I wouldn't advise this as users cant tell if the operation was successful or not) or you can throw the exception up a level so that it can be handled else where. The whole point of a try catch is to handle unexpected specific behaviour, thus its not a good idea to catch generic exceptions unless you have a generic way of handling it.
When something went wrong we can't just ignore it; if we don't have enough information to make a decision, a best option is to escalate the problem: may be a top level method knows what to do.
So I suggest to rethrow the exception instead of returning any value:
private static T LoadData<T>(string filePath)
{
try
{
return JsonUtility.FromJson<T>(File.ReadAllText(filePath));
}
catch(Exception e)
{
// Something went wrong, so lets get information about it.
Debug.Log(e.ToString());
// let top level method decide what to do:
// 1. Do nothing (just ignore the exception)
// 2. Do something (e.g. change permission) with filePath
// 3. Try load from some other file
// 4. Try load from some other source, say RDBMS
// 5. Use some default value
// 6. Close the application
// 7. ....
throw;
}
}
Please note, that here, within LoadData<T> method we don't know the context, and that's why we can't decide which option from 1..7 is the best one
I don't quite get the topic "proper exception handling" into my head.
"Exceptions should only be caught only if you can do something to fix
that exceptional situation".
I don't understand this. For example:
If I do not catch FormatException thrown by Convert.toInt(), even if it's just to show the exception message to the user, my program just crashes. If I had caught this exception and just told the user that the input had the wrong format, it would have survived.
So, should I catch such exceptions or not?
Exceptions should only be caught only if you can do something to fix
that exceptional situation
fixing maybe not the best word here. You should catch exception if you can handle it. Handling may mean:
fixing problem or returning some default values
retrying something
logging or notifying user (I believe every exception should be logged, even if you can fix it)
throwing more high-level exception
But you should not catch exceptions and do nothing:
catch(FormatException ex)
{
}
That just swallows exception and you will never know if something bad happened.
It doesn't means that you let the exception unhandled. It means that the proper flow of application is not possible therefore the code should return and notify the caller (an exception or a message). And in your case as the input is invalid therefore you should handle the exception and let the caller know of what is wrong here.
This is a difficult one to answer and it of course depends on your design, application preferences.
When handling exceptions I try to follow these rules:
Only catch an exception I can handle and recover from (for example send a notification email). It's possible for the application to continue doing it's task and simply not notify the user - you don't want the process it's notifying to crash simply because your email server is down.
Don't program by exception, use a int.TryParse( ) by preference to check rather than relying on exceptions to dictate the program flow.
Always catch exceptions before they hit the service boundary. This may be the UI, a WebService or some interface. You should not show a user an exception, instead it should be logged and a pretty user friendly message (or error code) returned to the consumer.
Of course everyone has different opinions on error handling so it's difficult to get a definitive answer. My suggestion would be to build up your own set of rules (unless someone is paying you in which case follow theirs!).
In other words, do not catch exceptions you do not know how to handle. Ultimately any exception should be handled at some point (so your program does not crash) but you should have a sound strategy when and how to do it.
Yes, I think you should catch this exception because actually you can treat it in you catch block by warning the user his input has wrong format.
There's other solutions to avoid the possibility to have a format exception like for example if you ask for an integer and your application's a WPF/Winform/Web application you can use a NumericUpDown control in order to ensure the user enter an integer. Also you can use this kind of code so you won't have to manage exceptions :
if (int.TryParse(userEnteredValue, out resultInt))
{
}
If I do not catch FormatException thrown by Convert.toInt(), even if it's just to show the exception message to the user, my program just crashes.
Right, and this is a case of an exception which can be handled properly. bad input from a user is expected to occur, this, you should handle it.
There are other classes of errors though, things which you can do little about. For example, an OutOfMemoryException.
"Fixing" this situation is not necessarily correcting it. When you catch an error and inform the user about this error, that might be sufficient to "fix" it. E. g. you can let the user correct the input.
Your quote means that you should not do something like this:
try
{
// do something which can throw
}
catch(Exception ex) // even this is bad practice as you should try to catch specific exceptions
{
// do nothing
}
It depends on what the usability you can provide to the user while catching that particular exception.
Let's say you are doing some calculation based on the paramters entered by the user and there is one field that is optional.
Now, if the user enters some string for that field instead of numeric field, your program will crash, if you have not caught exception.
Bu, even if you caught that exception, you calculation will not be completed as you will be skipping the calculation after the exception is thrown.
But what you can do in this situation is, check if FormatException is thrown for that optional field. If yes, ignore the exception using a catch and set the value to some default value, say 0 and then proceed as usual with you calculation.
We have a requirement of parsing/validating a large number of rows read from CSV or Excel files. We read the row and apply business rules to check if all the cells/columns contain the valid data.
The application should keep validating records/columns till end even if some error occurs at an error or column. Currently we are going like this:
private void ValidateRow(RowObject obj)
{
try
{
foreach(var col in obj.Cells)
{
ValidateColumn(col);
}
}
catch(Exception ex)
{
//LOG ERROR
}
}
The columns are validates like this:
public void ValidateColumn(ColumnObject c)
{
try
{
//validate c
}
catch(Exception e)
{
//LOG Column Error
}
}
We are handling error at two places when validating rows (ValidateRow) and then for each column (ValidateColumn). My question is whether this is valid or optimal way of handling error or something more optimal be done?
Since we don't know your Business logic it's difficult to tell. But I would recommend to evaluate all possible exceptions and handle them in different catch blocks. This enables you to handle errors more specific. A good hint is to use Microsofts StyleCop and FxCop. They help you to write good code. In this case they would tell you to not catch general Exceptions.
I think your way is very correct and optimal. If you want to keep going, you should always have a try/catch inside the foreach. But I guess you don't really need the outer try/catch in this case as it will only fail if obj or obj.Cells is null. Unless you have posted only part of your code. Though I agree with comments that validation should not throw exception in the first place but if you are using some 3d party library or any complex code that you are not sure of, it's better to handle it the way you did.
I got the question:
"What do you prefer, exception handling or if-condition?"
for an interview. My answer was that exception handlers are preferred only for exceptional circumstances like a disk permission error on file write. The interviewer seemed to be expecting some other answer. What is the correct answer?
EDIT: Any particular example where exception handling is commonly used when an if-condition would have been more appropriate?
As this question is tagged "C#", we can refer to the .NET Framework Design Guidelines as a good starting point for answering these types of questions. This is the guidance given on MSDN under "Exception Throwing":
Do not use exceptions for normal flow of control, if possible. Except
for system failures and operations with potential race conditions,
framework designers should design APIs so that users can write code
that does not throw exceptions. For example, you can provide a way to
check preconditions before calling a member so that users can write
code that does not throw exceptions.
Here is an example of a bad practice where an exception is handled but can nearly always be avoided:
public int? GetItem(int index)
{
int? value = null;
try
{
value = this.array[index];
}
catch (IndexOutOfRangeException)
{
}
return value;
}
This seems contrived but I see code like this quite often from newer programmers. Assuming proper synchronization around reads and writes to array, this exception can be 100% deterministically avoided. Given that, a better way to write that code would be the following:
public int? GetItem(int index)
{
int? value = null;
// Ensure the index is within range in the first place!
if (index >= 0 && index < this.array.Length)
{
value = this.array[index];
}
return value;
}
There are other cases where you cannot reasonably avoid exceptions and just need to handle them. This is most commonly encountered when you have to deal with external resources such as files or network connections which you could potentially lose access to or contact with at any time. Example from WCF:
public void Close()
{
// Attempt to avoid exception by doing initial state check
if (this.channel.State == CommunicationState.Opened)
{
try
{
// Now we must do a (potentially) remote call;
// this could always throw.
this.channel.Close();
}
catch (CommunicationException)
{
}
catch (TimeoutException)
{
}
}
// If Close failed, we might need to do final cleanup here.
if (this.channel.State == CommunicationState.Faulted)
{
// local cleanup -- never throws (aside from catastrophic situations)
this.channel.Abort();
}
}
Even in the above example, it's good to check that the operation you are going to do at least has a chance of succeeding. So there is still an if () check, followed by the appropriate exception handling logic.
Exception handling is a heavy and expensive operation as far as performance is concerned. If you can avoid catching an exception by using proper if else that can increase application's performance
On the other hand if else block makes more sense to code reader. They are easy to understand and maintain as compared to exceptional try catch block. They describe the program flow in more elegant manner
And finally as you said Exception handling should be for uncertain situations or for exceptional cases it should not be the default choice
Edit
A common bad practise I have seen at some places is this
try
{
string str = "Some String"
int i = Convert.ToInt32(str);
}
catch (Exception ex)
{
MessageBox.Show("Invalid input");
}
Now try catch can be easily avoided in this casing by using if else
string str = "Some String"
int i;
if(!int.TryParse(str, out i))
{
MessageBox.Show("Invalid input");
}
The correct answer is just the one that you gave.
For greater specificity, you should've said something to the effect of "I use if statements wherever possible due to the overhead of catching and throwing exceptions".
I normally prefer to use some special undefined value (e.g. null for objects) to indicate that some computation could not produce a valid result because of invalid input. This means that my code could successfully determine and report that the input data is invalid and no meaningful result can be produced.
I prefer to use an exception when my code cannot complete the requested computation, e.g. if a file containing some required data does not exist, if it cannot connect to a database.
So conceptually:
Undefined result (plus if-condition): program successfully determines that there is no valid output for the given input.
Exception (plus try-catch): program cannot complete computation due to some error in the application not related to the input.
If you know the exact login of the program and knows the errors that can occur then you can write if-else statement or in other case you can leave things to try catch exception handling.
I am currently in a try catch finding if a property has been set properly to the bool value that it should be like this...
public void RunBusinessRule(MyCustomType customType)
{
try
{
if (customType.CustomBoolProperty == true)
{
DoSomething();
}
else
{
throw new Exception("This is obviously false or possibly null lets throw up an error.");
}
}
catch(Exception)
{
throw;
}
}
Now the deal with throwing this error for me is that I am using Microsoft's source analysis and it gives me an error stating "CA2201 : Microsoft.Usage : Object.RunBusinessRule(MyCustomType)creates an exception of type 'Exception', an exception type that is not sufficiently specific and should never be raised by user code. If this exception instance might be thrown, use a different exception type.
Soooo What exception should I throw that would be specific enough for Microsoft.., for the circumstance of throwing an error about my own application's logic handling and when I want to "throw".
ArgumentException
InvalidOperationException
FormatException
The passed in argument wasn't good.
Create your own exception extending Exception. E.g.: RuleViolationException
Should you be throwing an exception at all?
Having a false boolean value isn't exactly an exceptional circumstance.
EDIT
My original answer was a bit terse so I'll elaborate...
From your example it's not clear what the actual objects, properties and methods represent. Without this information, it's difficult to say what type of exception, if any, is appropriate.
eg, I'd consider the following a perfectly valid use of an exception (and your real code might well look something like this, but we can't tell from your example):
public void UpdateMyCustomType(MyCustomType customType)
{
if (!customType.IsUpdateable)
throw new InvalidOperationException("Object is not updateable.");
// customType is updateable, so let's update it
}
But in the general case, without knowing more about your domain model, I'd say that something like this (a false boolean value) isn't really exceptional.
ArgumentException maybe?
A case could be made for InvalidOperationException, too.
The answer here is that you shouldn't throw any exception. Why throw an exception just to catch it again in a second and rethrow it?
A slight aside, but you could simplify your code somewhat...
public void RunBusinessRule(MyCustomType customType)
{
if (customType.CustomBoolProperty == false)
{
throw new Exception("This is obviously false or possibly null lets throw up an error.");
}
DoSomething();
}
As for the type of exception to throw, you might consider ApplicationException or InvalidOperationException, or you could define your own exception type.
I know that a question is about throwing an exception but I think it would be more appropriate to do an assertation here:
// Precondition: customType.CustomBoolProperty == true
System.Diagnostics.Debug.Assert(customType.CustomBoolProperty)
DoSomething();
InvalidArgument exception is fine but better yet, an ApplicationException.
The other answers are fine for quick resolution, but ideally if you know at compile time that a certain method should never be invoked using certain parameters, you can prevent that from ever happening by inheriting your custom type, instanciating it only when that custom bool is true, and now your method looks like.
public void RunBusinessRule(MyInheritedType inheritedObject)
{
//No need for checks, this is always the right type.
//As a matter of fact, RunBusinessRule might even belong to MyInheritedType.
}
This is the I in SOLID.
I think you should avoid exceptions for code logic.
I suggest to modify your method to return the result of your method as a bool type then you may decide the appropriate way to show an error message to the user at the time of calling the method:
public bool RunBusinessRule(MyCustomType customType)
{
try
{
if (customType.CustomBoolProperty == true)
{
DoSomething();
return true;
}
return false;
}
catch(Exception)
{
throw;
}
}
Make your own custom exception by extending System.Exception and throw that. You can get even crazier and have a whole tree of exception types if you want.
You could just create a custom ValidationException that is only used for your business logic validation. Or you could create a separate validation exception for each type of validation error although that is probably overload.
Not really what you were asking for, but there are plenty of people who have already given answers that I agree with, but you should also avoid only using catch(Exception ex).
It is a much better practice to try to catch the specific Exceptions that are possible first and if need be, catch the generic Expception. eg:
try{
MyMethod(obj);
}catch (NullReferenceException ne){
//do something
}
catch(UnauthorizedAccessException uae){
//do something else
}
catch(System.IO.IOException ioe){
//do something else
}
catch(Exception){
//do something else
}