I'm a beginner and haven't had a job yet, so I never work experience with code.
My question is:
How should I handle situations, when user enters a value, that doesn't throw exception, but is unacceptable and and program should be closed.
Should I throw an exception with some message in catch block, or it would be enough to just show a message ?
Its really up to the requirements of the application that you are developing. But c# has a specific exception type for this:
InvalidArgumentException
And you can use it like this:
if (!ValidateUserInput(input))
throw new InvalidArgumentException ("input is invalid");
You can then catch that further up in the application and decide how to handle it
It all depends of You. Depends on what You want to achieve.
There is no ultimate answer to this.
It is good to do everything You said. Throw exeption in try catch block and then give a information for user and close program.
Additionally log the error with more informataion to a file or databases.
Message box is good, because is user firendly.
Throw exeption is also good because is very readable for developer - when they read You code they see this is a bad sitiation.
For example what to do:
try
{
if (IsErrorValidation())
{
throw new Exeption("You input wrong data");
}
}
catch (Exception e)
{
MessageBox.Show("Error" + e.Message );
CloseProgram();
}
You create new Exception with Your massage.
Better is create Your own type of Exeption for example ErrorValidationException or use the predefined InvalidArgumentException which exist in C#
try
{
if (IsErrorValidation())
{
throw new ErrorValidationException("You input wrong data");
}
}
catch (ErrorValidationException e)
{
MessageBox.Show("Error" + e.Message);
CloseProgram();
}
catch (Exeption e)
{
...
}
Then You can use this type of exception later and You can serve this type of exception in a different way
Related
This might be a broad question, but recently I ahve wondered about the following: In our C# backend we have many places that wrap some code in a try/catch block, specifically calls to external WcF services. Some of these calls are crucial for the application so in the catch block we log the error and rethrow, like:
catch(Exception ex)
{
_logger.Error("Some good error message");
throw ex;
}
On the other hand there are services we allow to fail, but we still want to log the error, so they look like:
catch(Exception ex)
{
_logger.Error("Some good error message");
}
Now reading the code of team members I can not be sure if they forgot to throw or if this is the intended behaviour.
Q: Is there a way, resp. what is the default way, to explicitly NOT rethrow (without including a comment in the code).
I have considered something like this:
catch(Exception ex)
{
_logger.Error("Some good error message");
NotThrowingHereOnPurpose();
}
// ...
// and further below a private method
// ...
private void NotThrowingHereOnPurpose(){}
One approach that may be useful here is to change the way of invoking the code that you explicitly allow to fail in such a way that it does not look like a try/catch block at all.
For example, you could write a helper method that does error reporting, and call it with actions expressed as lambdas:
void InvokeFailSafe(Action action, Action<Exception> onFailure = null) {
try {
action();
} catch (Exception e) {
if (onFailure != null) {
onFailure(e);
}
}
}
Now instead of try/catch you would write this:
InvokeFailSafe(
() => {
... The code that may fail
}
, exception => _logger.Error("Some good error message: {0}", exception)
);
or like this, if you don't want anything logged:
InvokeFailSafe(
() => {
... The code that may fail
}
);
If you code things this way, there would be no doubts about a missing throw statement.
It's an opposite solution to dasblinkenlight's answer. Instead of notifying others that the exception mustn't be rethrown it would say that it must be.
If you only want to log it then use the Error method as usual. Otherwise, you can write an extension method for your logger to log and throw exceptions.
The method would take the catched exception and rethrow it using the ExceptionDispatchInfo class. The ExceptionDispatchInfo is used to rethrow the exception with the original stack trace information and Watson information. It behaves like throw; (without the specified exception).
public static void ErrorAndThrow(this ILogger logger, string message, Exception exception)
{
var exceptionInfo = ExceptionDispatchInfo.Capture(exception);
logger.Error(message);
exceptionInfo.Throw();
}
And use it this way:
try
{
}
catch (Exception ex)
{
// ex would be rethrown here
_logger.ErrorAndThrow("Some good error message", ex);
}
Q: Is there a way, resp. what is the default way, to explicitly NOT
rethrow (without including a comment in the code).
Ideal way would be not to catch a generic exception. Now, to throw or not that entirely depends on your case. You need to understand that Exception handling is used when you know what to do in case an exception occurs. So, only specific exceptions should be handled. Catching exceptions without knowing what you are catching will change the behavior of your application.
Now reading the code of team members I can not be sure if they forgot
to throw or if this is the intended behaviour.
This is something the author of the code can explain to you. But here is a learning to take from this. Your code should be self explanatory. In specific cases where you are unable to express yourself with the code, add a meaningful comment.
You can check this link for better understanding.
I actually found another way that kind of includes what other have suggested here, but uses a built in feature: exception filters. I was free to modify the example given in here to illustrate this:
public void MethodThatFailsSometimes()
{
try {
PerformFailingOperation();
}
catch (Exception e) when (e.LogAndBeCaught())
{
}
}
and then one could have two extension methods on Exception, say LogAndBeCaught and LogAndEscape like so:
public static bool LogAndBeCaught(this Exception e)
{
_logger.Error(#"Following exception was thrown: {e}");
return true;
}
public static bool LogAndEscape(this Exception e)
{
_logger.Error(#"Following exception was thrown: {e}");
return false;
}
I want a better way to catch database error details.
I'm currently using :
try
{
dbconn.table.AddObject(newRow);
dbconn.SaveChanges();
}
catch (Exception ex)
{
Console.WriteLine("DB fail ID:" + Row.id);
}
many times I found the Exception ex can no give me details on how the exception happen.
I think these exception most likely to be the DB connection kind.
So is there a better way to catch this ?
You should also output the exception. Most of the time, it holds useful and detailed information (e.g. names of violated constraints). Try this:
try
{
dbconn.table.AddObject(newRow);
dbconn.SaveChanges();
}
catch (Exception ex)
{
Console.WriteLine("DB fail ID:" + Row.id);
Console.WriteLine(ex.ToString());
}
For full details, use the ToString() method, it will give you the stack trace as well, not only the error message.
Use Console.WriteLine(ex.GetType().FullName) (or put a breakpoint and run under a debugger) to see the actual exception type being thrown. Then visit MSDN to see its description and base classes. You need to decide which of the base classes provides you with the information needed by exposing such properties. Then use that class in your catch() expression.
For Entity Framework, you might end up with using EntityException and then checking the InnerException property for the SQL exception object that it wraps.
try
{
dbconn.table.AddObject(newRow);
dbconn.SaveChanges();
}
catch (EntityException ex)
{
Console.WriteLine("DB fail ID:" + Row.id + "; Error: " + ex.Message);
var sqlExc = ex.InnerException as SqlException;
if (sqlExc != null)
Console.WriteLine("SQL error code: " + sqlExc.Number);
}
Instead of Exception use SqlException.
SqlException give you more detail. it has a Number property that indicate type of error and you can use that Number in a switch case to give some related information to user.
In short, yes there is a better way to handle it. The 'how' of it is up to you.
Exception handling in C# goes from the most specific exception type to the least specific. Also, you aren't limited to using just one catch block. You can have many of them.
As an example:
try
{
// Perform some actions here.
}
catch (Exception exc) // This is the most generic exception type.
{
// Handle your exception here.
}
The above code is what you already have. To show an example of what you may want:
try
{
// Perform some actions here.
}
catch (SqlException sqlExc) // This is a more specific exception type.
{
// Handle your exception here.
}
catch (Exception exc) // This is the most generic exception type.
{
// Handle your exception here.
}
In Visual Studio, it is possible to see a list of (most) exceptions by pressing CTRL+ALT+E.
Newby question...
Is it valid to do:
try
{
// code which may fail
}
catch
{
Console.Writeline("Some message");
}
Or do I always have to use:
try
{
// code which may fail
}
catch (Exception e)
{
Console.Writeline("Some message");
}
Both blocks are valid.
The first will not have an exception variable.
If you are not going to do anything with the exception variable but still want to catch specific exceptions, you can also do:
try
{
// your code here
}
catch(SpecificException)
{
// do something - perhaps you know the exception is benign
}
However, for readability I would go with the second option and use the exception variable. One of the worst things to do with exceptions is swallow them silently - at the minimum, log the exception.
Yep, absolutely, such a catch block called general catch clause, see more interesting details in the C# Language Specification 4.0, 8.10 The try statement:
A catch clause that specifies neither an exception type nor an
exception variable name is called a general catch clause. A try
statement can only have one general catch clause, and if one is
present it must be the last catch clause
Yes, your first block of code valid. It will catch all exceptions.
It is. It will catch all the exception. So the two code examples do the same.
First one is valid, and it acts just like the second one.
http://msdn.microsoft.com/en-us/library/0yd65esw%28v=vs.80%29.aspx
The catch clause can be used without arguments, in which case it
catches any type of exception, and referred to as the general catch
clause. It can also take an object argument derived from
System.Exception, in which case it handles a specific exception.
Yes it is valid.
you can always refer to this article:
Best Practices for Handling Exceptions on MSDN
Of course it is valid, you specify catch(Exception e) when you want to output the error message ex.Message, or to catch a custom or a concrete Exception. Use catch in your situation.
As #David answered this is valid.
You could use second syntax if you want to get more infos or catch a specific exception.
E.g.
catch (Exception e)
{
Debug.Print(e.Message);
}
catch (Exception e)
{
Console.Writeline("Some message");
}
In this block you can use SqlException, etc..
catch (SqlException e)
{
Console.Writeline("Some message");
}
For this use the "(SqlException e)"
If you will use a generic menssage, use this:
catch
{
Console.Writeline("Some message");
}
or
catch (Exception)
{
Console.Writeline("Some message");
}
Don't forget that you can chain catch your exceptions. This will allow you to handle different scenarios based upon the exception(s) the code may throw.
try
{
//Your code.
}
catch(SpecificException specificException)
{
//Handle the SpecificException
}
catch(AnotherSpecificException anotherSpecificException)
{
//Handle AnotherSpecificException
}
catch(Exception exception)
{
//Handle any Exception
}
Is it possible to call catch for a special condition when you are inside of try without using system error? For instance if a value int value 1 and then I want to use "catch".
One of the biggest sins in programming:) Don't use exceptions for managing programming flow! Now to your question - the catch block can be called in case an exception is thrown.
Your wording is a bit confusing but I think this is what you want.
int value = GetValue();
try
{
if (value == 1)
throw new InvalidOperationException();
HappyPath(value);
}
catch (InvalidOperationException)
{
SadPath(value);
}
Incidentally using exceptions for control flow is not the best practice.
No. You should catch exceptions (you can filter them by type), and then inside catch block you can filter on any condition.
It is not possible in C# to throw an exception that doesn’t derive from Exception, even though the CLR allows it.
It is possible to catch such an exception, but it is not possible to access the object that was thrown:
try
{
MethodThatThrows();
}
catch // This catches everything, even objects not deriving from Exception
{
// Process exception
}
As soon as you specify a variable (e.g. catch (Exception e)), C# requires that the type is Exception or derived from it.
I think you might be saying that you want to catch an exception only in specific circumstances, and pass it through in all other circumstances? In that case, you can just use an if to check for the condition and then throw to re-throw the exception:
try
{
// ...
}
catch (Exception e)
{
// If it’s any value other than 1, we’re not interested in the exception
if (value != 1)
throw; // note: throw; *not* throw e;
// Process the exception here
}
this is a really basic question (I hope). Most of the exception handling I have done has been with c#. In c# any code that errors out in a try catch block is dealt with by the catch code. For example
try
{
int divByZero=45/0;
}
catch(Exception ex)
{
errorCode.text=ex.message();
}
The error would be displayed in errorCode.text. If I were to try and run the same code in php however:
try{
$divByZero=45/0;
}
catch(Exception ex)
{
echo ex->getMessage();
}
The catch code is not run. Based on my limeted understanding, php needs a throw. Doesn't that defeat the entire purpose of error checking? Doesn't this reduce a try catch to an if then statement?
if(dividing by zero)throw error
Please tell me that I don't have to anticipate every possible error in a try catch with a throw. If I do, is there anyway to make php's error handling behave more like c#?
You could also convert all your php errors with set_error_handler() and ErrorException into exceptions:
function exception_error_handler($errno, $errstr, $errfile, $errline )
{
throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
}
set_error_handler("exception_error_handler");
try {
$a = 1 / 0;
} catch (ErrorException $e) {
echo $e->getMessage();
}
PHP's try-catch was implemented later in the language's life, and so it only applies to user-defined exceptions.
If you really want to handle actual errors, set your own error handler.
To define and catch exceptions:
function oops($a)
{
if (!$a) {
throw new Exception('empty variable');
}
return "oops, $a";
}
try {
print oops($b);
} catch (Exception $e) {
print "Error occurred: " . $e->getMessage();
}
From http://php.net/manual/en/language.exceptions.php
"Internal PHP functions mainly use Error reporting, only modern Object oriented extensions use exceptions. However, errors can be simply translated to exceptions with ErrorException."
See also http://www.php.net/manual/en/class.errorexception.php
I think the only way to deal with this in PHP is to write:
try
{
if ($b == 0) throw new Exception('Division by zero.');
$divByZero = $a / $b;
}
catch(Exception ex)
{
echo ex->getMessage();
}
Unlike in C#, not every issue will raise an exception in PHP. Some issues are silently ignored (or not silently - they print something to the output), but there are other ways to handle these. I suppose this is because exceptions were not a part of the language since the first version, so there are some "legacy" mechanisms.