I have a system where the employeeId must alway exist unless there is some underlying problem.
The way I see it, is that I have two choices to check this code:
1:
public void GetEmployee(Employee employee)
{
bool exists = EmployeeRepository.VerifyIdExists(Employee.Id);
if (!exists)
{
throw new Exception("Id does not exist");
}
}
or 2:
public void GetEmployee(Employee employee)
{
EmployeeRepository.AssertIfNotFound(Employee.Id);
}
Is option #2 acceptable in the C# language?
I like it because it's tidy in that i don't like looking at "throw new Exception("bla bla bla") type messages outsite the class scope.
As a rule, you should only throw exceptions in exceptional circumstances. Since this one such circumstance, throwing an exception is the right thing to do.
It depends what you mean by Assert.
You could use Debug.Assert (or Trace.Assert if you want it to also work in release mode). However this is not that useful because it halts the program and pops up a dialog box until a user presses something. This isn't so good for an unmonitored system. So I'd recommend throwing instead in most cases though as you can decide how you want to react to the error - stop the program, or just log and try to continue.
But if we assume that your Assert method checks its argument and possibly throws an exception, then yes I think that's a good way of doing it.
In fact to pick an example, in Jon Skeet's morelinq both methods are used. For example here:
public static IEnumerable<TSource> AssertCount<TSource>(
this IEnumerable<TSource> source,
int count,
Func<int, int, Exception> errorSelector)
{
source.ThrowIfNull("source");
if (count < 0) throw new ArgumentException(null, "count");
errorSelector.ThrowIfNull("errorSelector");
return AssertCountImpl(source, count, errorSelector);
}
Use exceptions, its what they are there for - exceptional circumstances.
All the standard .NET libraries use this method of handling such circumstances so takes your cues from Microsoft.
The idea behind assertions, as I've always used them, are that they are instant feedback when running a debug build. Kind of an in your face that something happened. Or logged to file if the app is setup that way.
Exceptions are used to handle exceptional behavior, as noted above.
What I do, especially early in projects life cycle might be something like:
public void GetEmployee(Employee employee)
{
bool exists = EmployeeRepository.VerifyIdExists(Employee.Id);
Debug.Assert( exists, "employee does not exist for id: " + Employee.Id );
if (!exists)
{
throw new Exception("Id does not exist);
}
}
Perhaps refractoring out the Debug.Assert once the initial hiccups are dealt with.
Related
I'm so used to check if a method's argument is null (then proceed to throw an exception) that I almost don't even think about it anymore.
If the argument is a reference type, it's there:
if(arg == null)
throw new ArgumentNullException(nameof(arg));
But what if I'm going to use arg immediately? Should I check anyway? I mean, if I don't, the envinroment will throw for me (a NullReferenceException) anyway.
For instance:
public int DoStuff(object o)
{
return o.GetHashCode();
}
I could write add the null check easily:
public int DoStuff(object o)
{
if(o == null)
throw new ArgumentNullException(nameof(o));
return o.GetHashCode();
}
But in both cases a exception will be thrown (in almost the exact same line, for debugging purpose). The only difference is the type.
The question: On public methods with a single reference type argument, if I'm going to use the argument immediately, should I still check it if it's null?
I suggest checking, because you have two Exception types:
Unexpected NullReferenceException - something went wrong, and you have to debug your own routine
ArgumentNullException - the argument is null, and it's caller that's wrong (and not your code which reacts right)
throwing ArgumentNullException is kind of contract: I'll do the thing in case argument is correct:
// An exaggerated example
public int DoStuff(SomeObject o) {
if (o == null)
throw new ArgumentNullException(nameof(o));
else if (o.Disposed)
throw new ArgumentException(nameof(o), "o must not be disposed")
else if (o.Id > 100)
throw new ArgumentOutOfRangeException("Id ...", nameof(o));
// o meets the contract, we accept it and thus we guarantee the output
return o.SomeMethod();
}
This kind of validation is typical for public (protected) methods since they're exposed to outer world and can face any argument; however, in case of private method you can omit the contract: any caller is within the class that implements the method.
Well, it depends ;)
This is my take on it, and the question is (kinda) subjective.
IMO, if the code throws a NullReferenceException, it means that the code itself has no internal consistency. It is a sign of lazyness and should be avoided at all costs.
If a method throws a NullReferenceException, it is method's fault.
An ArgumentNullException, on the other hand, means that the method cannot "do it's stuff" if the argument is null.
It becomes responsibility of the invoker to guarantee that the parameter is not null, or handle graciously the exception.
Bottom line: an ArgumentNullException is a contract, a NullReferenceException is a bug.
I suppose if you are immediately dereferencing the variable, you could debate either way, but I would still prefer the ArgumentNullException.
It is much more explicit about what is going on. The exception contains the name of the variable that was null, whereas a NullReferenceException does not.
I strongly suggest you check for null at the top of the method.
Think of that as a "contract" that specifies the following:
In order for this method to execute, this argument must be non-null.
Doing the null check is great documentation. You could go one step further an use XML comments e.g.
/// <summary>
///
/// </summary>
/// <param name="arg1"></param>
/// <exception cref="ArgumentNullException">If <paramref name="arg1"/> is NULL.</exception>
private static void Foo(object arg1)
{
}
I'd say it depends more on how you handle the errors, not how they're thrown. An example will help. Imagine this is the method instead of what you have:
public static int DoStuff(string o) {
return Int.Parse(o);
}
If you have this, then it really doesn't matter.
public static void main(string[] args)
{
try {
Console.Write("Enter a number: ");
value = DoStuff(Console.ReadLine());
}
catch(Exception ex) {
Console.WriteLine("An exception was thrown. Contents: " + ex.ToString());
}
}
Either way your program flow is the same. But if you have below:
public static void main(string[] args)
{
try {
int value = 0;
do {
try {
Console.Write("Enter a non-zero number to stop: ");
value = DoStuff(Console.ReadLine());
}
catch(ArgumentException ex) {
Console.WriteLine("Problem with input, try again. Exception message was: " + ex.Message);
continue; // Or just nothing, will still loop
}
} while(value == 0);
}
catch(Exception ex) {
Console.WriteLine("An exception was thrown. Contents: " + ex.ToString());
}
}
Basically, if your error handling doesn't care which exception type it is, then it's just extra code that probably doesn't help you. But if you handle specific things differently, then it may be worth it to test and throw the more specific type of exception.
But I do agree with Dmitry's post above that a public method matters a lot more than a private one. Your signature for the method is somewhat like a contract. It's best to enforce it.
There are a few different scenario's I think you should consider:
The method is called from your own program. You don't expect a null value. You use the object somewhere down the line and if it's null, it will still change the state.
The method is called from your own program. You don't expect a null value. If it's a null, it won't change the state and everything will continue to be consistent.
The method is exposed through a library or API. An unknown developer X calls the method with whatever you want.
You just want to know that an argument is not null while implementing stuff. To protect yourself and your team members.
Points (1) and (2) are about exception safety. Basically this states that regardless of your input, the state of your data structures should be consistent. In most cases this is resolved through a simple check; in more complex scenario's it might involve a rollback or a more complex piece of machinery. So:
If you add a null value to a database, you don't want it to mess up your database. Now, you can of course solve null values by simply checking your assumption. If the argument is null, throw an ArgumentNullException because that best describes the scenario.
If you call a method that doesn't expect a null value and it won't influence the rest of your system, I usually put a comment somewhere and let nature run its course. A NullReferenceException tells me enough about the nature of the bug.
If it's an API, people expect certain behavior (e.g. a ArgumentNullException). Moreover, as a developer you shouldn't trust the big bad outside world so you should check anyways.
If you just want to protect yourself and your team members, use an Assertion. Assertions are usually implemented in such a way, that they don't end up in release code (or at least have no impact on your speed), will automatically trigger a breakpoint and will fail your unit test. They're also easy to recognize so they won't add too much bloat to your code.
To summarize, I wouldn't just put checks everywhere; they tend to make your code unreadable and bloaty. That said, if I would put a check to ensure exception safety, it's best to use the exception that best describes the error.
Follow Einstein - "make things as simple as possible, but no simpler". Does that code do the same thing without a line of code? If so, it is probably best to remove it.
I am writing a method (for a service) that returns a specific error code to the client.
Inside this method I am calling various LINQ extension methods. Each one of these extension methods can throw exceptions of 'same' type (say InvalidOperationException), but I need to catch these exceptions individually and return a specific error code. Here is what it looks like now (much simplified version)
public errorCode SomeMethod()
{
try
{
var foo1 = SomeDataSource.Entities1.Single(x=> x.bar1 == somevalue);
}
catch(InvalidOperationException x)
{
return ErrorCode1;
}
try
{
var foo2 = SomeDataSource.Entities2.Single(x=> x.bar2 > somevalue);
}
catch(InvalidOperationException x)
{
return ErrorCode2;
}
......
This is adding up to be a lot of try-catch blocks, as there are several error conditions that can potentially exist. It is also forcing me to elevate the scope of variables like foo to outside the individual try blocks, as they are being used in subsequent try blocks.
I am just curious to see if there is a way to consolidate all this code in a more elegant manner (some inline methods perhaps?) so that it doesn't end up looking so intimidating?
Based on the feed back I got, I have to add that the Business Rules that I am trying to implement leads me to use 'Single' and not 'SingleOrDefault'. Using 'SingleOrDefault' makes it easier because then we can just check for null without catching the exception. 'Single' on the other hand simply throws an exception if the condition fails. Idea here is to consolidate all these try blocks where as somehow keep all the errors happening separate even though every call to 'Single' throws the same type of exception (InvalidOperationException)...
Thanks
You are misusing exceptions for control flow. Better:
var foo1 = SomeDataSource.Entities1.SingleOrDefault(x=> x.bar1 == somevalue);
if (foo1 == null) return ErrorCode1;
Very clean and simple.
What's especially vexing in the original code is that you are treating all occurrences of InvalidOperationException as the same thing. Who knows whether that's true or not?! There can be many things throwing this particular exception type. You might hide bugs by catching too generously. You might even hide EF bugs this way.
If you want to move your business logic into the lambda method, which it sounds like, you can do so by defining an extension.
Note: I am not endorsing the code below at all; I'm just trying to make it fit the question that you have asked.
public static class LinqExtensions
{
public static ErrorCode BusinessSingle(this IEnumerable<TSource> enumerable, Func<TSource, bool> predicate)
{
TSource result;
try
{
result = enumerable.Single(predicate);
return new NoError(); // ????
}
catch
{
return new ErrorOne();
}
}
}
But it would be far better to do one of the following:
If errors are common, then don't treat it like an Exception but rather a validation rule.
If errors are exceptional, then throw Exception that are differentiated.
You're right that if you're always expecting exactly one element to match your condition, you should use Single() rather than SingleOrDefault().
That means that if that is not the case, your system is a faulted state, and your application should shut down because it is not working correctly. By saying Single(), you're saying "I know there's exactly one there. If there's not, there's something seriously wrong."
By trying to handle the exception and return an error code instead, you're saying something different. You're saying "There should be exactly one there, but if there's not, I can do something else to handle that case." That's what SingleOrDefault() is for.
So far I've learned that (usually) when you assert, you should also throw. At first I wasn't sure it was right, it just made sense1, and then this answer verified.
The problem I have is that it causes repeated-code (at least via contracts). Here's an example of a name field that can't be null or white-space:
public String Name
{
get { return _name; }
set
{
Contract.Requires(String.IsNullOrWhiteSpace(value) == false, "Names cannot be null or whitespace.");
if (String.IsNullOrWhiteSpace(value))
throw new ArgumentException("Names cannot be null or whitespace.");
_name = value;
}
}
Clearly both the condition, and the error message are repeated.
How should I handle it? In one property it's manageable but in a class with multiple fields it's littering.
Additional Information
I thought of using Contract.Requires<TException> (which would assert in debug and throw in release), but the condition (which is the code) would be the message of the exception, which would most likely be displayed to the user (a user would probably like to know why his program crashed, and I wouldn't want to show the actual code). Here's an example:
static void MyFunction(Boolean youCanSeeMyCode = false)
{
Contract.Requires<Exception>(youCanSeeMyCode, "(This is the exception's message)");
}
...
try
{
MyFunction();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error");
}
Any suggestions? I'm at a loss.
1 It made sense because if you only use assert and you still have a bug somewhere that you're unaware of, the release build would carry on as if everything's okay and hell could break loose.
The answer you've linked to is about Debug.Assert, which is turned off for release builds by default. I've never liked that idea - it's like saying that it's only worth wearing a seatbelt when you're learning to drive, but not when you're driving at speed.
I would encourage you to just use Contract.Requires (no separate explicit throw statement) and then make sure that you configure your project so that preconditions are still checked in release builds. Your concern about the message being displayed to the user isn't a concern which should be addressed here - it should be addressed in your general exception handling. If you don't want to show exception messages to the user, don't show them... but do log them. You really shouldn't try to make exceptions meaningful to end users... that's not their purpose.
This is not so much of a problem but more feedback and thoughts. I have been considering an implementation for methods that have been tested thoroughly through our internal teams. I would like to write a generic exception catch method and reporting service.
I relize this is not as easy as a "try-catch" block, but allows for a uniform method for catching exceptions. Ideally I would like to execute a method, provide a failure callback and log all the parameters from the calling method.
Generic Try-Execute.
public class ExceptionHelper
{
public static T TryExecute<T, TArgs>(Func<TArgs, T> Method, Func<TArgs, T> FailureCallBack, TArgs Args)
{
try
{
return Method(Args);
}
catch (Exception ex)
{
StackTrace stackTrace = new StackTrace();
string method = "Unknown Method";
if (stackTrace != null && stackTrace.FrameCount > 0)
{
var methodInfo = stackTrace.GetFrame(1).GetMethod();
if (methodInfo != null)
method = string.Join(".", methodInfo.ReflectedType.Namespace, methodInfo.ReflectedType.Name, methodInfo.Name);
}
List<string> aStr = new List<string>();
foreach (var prop in typeof(TArgs).GetProperties().Where(x => x.CanRead && x.CanWrite))
{
object propVal = null;
try
{
propVal = prop.GetValue(Args, null);
}
catch
{
propVal = string.Empty;
}
aStr.Add(string.Format("{0}:{1}", prop.Name, propVal.ToString()));
}
string failureString = string.Format("The method '{0}' failed. {1}", method, string.Join(", ", aStr));
//TODO: Log To Internal error system
try
{
return FailureCallBack(Args);
}
catch
{
return default(T);
}
}
}
}
What I know as draw backs.
Performance Loss using reflection
MethodBase (methodInfo) may not be available through optimization
The try-catch around the error handler. Basically I could use the TryExecute wrapper for the try-catch around the error call back however that could result in a stack overflow situation.
Here would be a sample implementation
var model = new { ModelA = "A", ModelB = "B" };
return ExceptionHelper.TryExecute((Model) =>
{
throw new Exception("Testing exception handler");
},
(Model) =>
{
return false;
},
model);
Thoughts and comments appreciated.
That's a lot of code to put in a catch, including two more try/catch blocks. Seems like a bit of overkill if you ask me, with a good amount of risk that a further exception can obscure the actual exception and that the error information would be lost.
Also, why return default(T)? Returning defaults or nulls as indications of a problem is usually pretty sloppy. If nothing else, it requires the same conditional to be wrapped around every call to the method to check for the return and respond to... some error that has gone somewhere else now.
Honestly, that usage example looks pretty messy, too. It looks like you'll end up obscuring the actual business logic with the error-trapping code. The entire codebase will look like a series of error traps, with actual business logic hidden somewhere in the entanglement of it. This takes valuable focus off of the actual intent of the application and puts something of background infrastructure importance (logging) at the forefront.
Simplify.
If an exception occurs within a method, you generally have two sensible options:
Catch (and meaningfully handle) the exception within the method.
Let the exception bubble up the stack to be caught elsewhere.
There's absolutely nothing wrong with an exception escaping the scope of the method in which it occurs. Indeed, exceptions are designed to do exactly that, carrying with them useful stack information about what happened and where. (And, if you add meaningful runtime context to the exception, it can also carry information about why.)
In fact, the compiler even subtly hints at this. Take these two methods for example:
public int Sum(int first, int second)
{
// TODO: Implement this method
}
public int Product(int first, int second)
{
throw new NotImplementedException();
}
One of these methods will compile, one of them will not. The compiler error will state that not all code paths return a value on the former method. But why not the latter? Because throwing an exception is a perfectly acceptable exit strategy for a method. It's how the method gives up on what it's doing (the one thing it should be trying to do and nothing more) and let's the calling code deal with the problem.
The code should read in a way that clearly expresses the business concept being modeled. Error handling is an important infrastructure concept, but it's just that... infrastructure. The code should practically scream the business concept being modeled, clearly and succinctly. Infrastructure concerns shouldn't get in the way of that.
This is very rarely going to be useful.
It covers only cases where:
The method has a well-defined means of obtaining an appropriate return value in the face of failure.
You'd actually care to log that it happened.
Now, 2 is very common with exceptions of all sorts, but not where 1 is true too.
1 of course is rare, since in most cases if you could produce a reasonable return value for given parameters by means X you wouldn't be trying means Y first.
It also has a default behaviour of returning default(T) - so null or all zeros - if the fallback doesn't work.
This only works where your case 1 above has "something that just returns null as a result because we don't really care very much what this thing does", or where the called method never returns null, in which case you then test for null, which means that your real error-handling code happens there.
In all, what you've got here is a way in which exceptions that would be trappable by real code have to be caught for by testing (and sometimes testing + guesswork) instead, and those that would bring down a program in a clear place with nice debugging information will instead put it into a state where you don't know what's going on anywhere, but at least of the few dozen bugs that got logged before something managed to bring it down fully, one of the is probably the actual problem
When you've a catch on some exception for a particular reason, by all means log the exception. Note that this is not so much to help find bugs (if that exception being raised there is a bug, you shouldn't be catching it there), but to cancel out the fact that having a catch there could hide bugs - i.e. to cancel out the very effect you are deliberately encouraging by putting catches all over the place. (E.g. you expect a regularly hit webservice to fail to connect on occasion, and you can go on for some hours with cached data - so you catch the failure and go on from cache - here you log because if there was a bug meaning you were never trying to hit the webservice correctly, you've just hidden it).
It's also reasonable to have some non-interactive (service or server) app log all exceptions that reach the top of the stack, because there's nobody there to note the exception.
But exceptions are not the enemy, they're the messenger. Don't shoot the messenger.
Is it a good idea to create a custom exception that would be thrown when an applicaiton logic fails which is expect to be handled?
Better to return an object or a value instead, I guess; but:
If not, then what is the correct conditions to introduce some custom exceptions into our code?
Thanks!
Yes, it is, assuming the issue you want to create it for is indeed an exceptional situation (i.e. should rarely happen, if ever).
If it is a normal error condition (something that you expect will happen on a regular basis and is part of normal usage of the application), you should code for it explicitly - in this case, creating and throwing a custom exception is a code smell.
Additionally, only create a custom exception if it adds information (over the built in ones).
Edit: (following comments)
Using exception handling as a form of flow control (i.e. did function X complete correctly or not) is pretty much always a bad idea and is a definite code smell.
You should create your own custom exceptions when you expect to perform an action based on the type of exception being thrown. If your purpose is to show the user a message then the type of exception being thrown means very little.
However, you need to be careful when you create your own exception types because there are many very good exception types already in the .NET platform and you should use one of those first. It's much better to have a FileNotFound exception as opposed to JoesBestFileNotFound exception.
Usually you can get by with standard exceptions. If you want to provide more useful debugging information the boost stuff could help.
You want to create your own exceptions when you want to provide information that goes beyond what the other options give you or when you want the user to be able to handle it in a unique manner. If all you're doing is mentioning that there is an exceptional situation then just use the wheel's that are already there to use.
I suggest always inheriting from std::exception or one of its derivatives.
It's always best practice to code without the possibility for exceptions to be thrown in the first place. If you need a reason: They're slow. Quantifiably slower than coding around them in even the most inelegant ways in most cases. That being said, sometimes they are unavoidable because of the code other people have written or they are desired because you really do want the program to blow up in the face of the user (see catastrophic failure). Only in these two cases is exception handling the way to go.
But this doesn't mean you wrap every IEnumerable<T>.First() in an if(sequence.Count() > 0). Learn to structure your code soundly, such that you don't ever call the .First() on an empty sequence in the first place. Elegant code is win.
I recently wrote a quick app for my employer to be used in an automated system (where the user does not sit at the keyboard) that must require the user to enter login information in command line args (think batch file) or a config file else it intentionally blows up in their face, as per spec. In this case, an exception is warranted.
All the code below demonstrates my philosophy on Exceptions.
private static string _password;
public static string Password
{
get
{
if (_password.IsNullOrWhiteSpace())
throw new NullReferenceException(string.Format("{0} {1}",
"Password was neither found in the .cfg file nor the",
"command line arguments."));
return _password;
}
set
{
_password = value ?? string.Empty;
}
}
An example of coding without exceptions in this extension method I just wrote.
public static bool All<T>(this IEnumerable<T> list, Func<T, T, bool> func)
{
if (list.Count() < 2)
return true;
T first = list.First();
return list.Skip(1).Aggregate(true, (i, k) => i && func(first,k));
}
Notice below I dealt with I/O Exceptions within the scope of the I/O method, but I parsed the data in the config file in such a way that my logic will never throw an exception. Note how The .Count() is verified to be 2 in all pieces of data. At this point, I can be confident that .First() and .Last() will not only be valid to the compilier and not throw exceptions, but be guaranteed to yield potentially valid pieces of data (non-whitespace, different values). This is the kind of philosophy I recommend you adapt when you think about Exception handling -> How do I filter and control my data in a referentially transparent way to completely eliminate errors within the scope of the method?
public static class ConfigParser
{
public static Dictionary<string, string> PullFromConfigFile()
{
ParallelQuery<Tuple<string, string>> data;
try
{
TextReader tr = new StreamReader("config.cfg");
data = tr.ReadToEnd()
.Split('\n')
.AsParallel()
.Select(i => new string(i.TakeWhile(k => k != '#').ToArray()))
.Where(i => !i.IsNullOrWhiteSpace())
.Select(i => i.Split('\t')
.Where(k => !k.IsNullOrWhiteSpace())
.Select(k => k.Trim())
)
.Where(i => i.Count() == 2)
.Select(i => new Tuple<string, string>(i.First(), i.Last()));
tr.Close();
}
catch (IOException)
{
Logger.Bad("config.cfg file was not found");
return new Dictionary<string, string>();
}
return ConfigParser.ParseIntoDict(data);
}
private static Dictionary<string, string> ParseIntoDict(ParallelQuery<Tuple<string, string>> data)
{
var agg = new Dictionary<string, string>();
foreach (var entry in data)
{
if (!agg.ContainsKey(entry.Item1))
agg.Add(entry.Item1, entry.Item2);
}
var width = agg.Keys.Max(k => k.Length);
agg.ForAll(i => Logger.Log("Loaded Data: {0} {1}",
i.Key.SetWidth(width, '-'), i.Value));
return agg;
}
}
Extensions used:
public static class Extensions
{
public static string SetWidth(this string item, int width, char padder, bool right = true)
{
if (item == null)
return new string(padder, width);
if (width > item.Length)
return right ? item.PadRight(width, padder) : item.PadLeft(width, padder);
return item.Substring(0, width);
}
public static bool IsNullOrWhiteSpace(this string str)
{
return string.IsNullOrWhiteSpace(str);
}
}
Generally you shouldn't use exceptions for normal program logic. It's fine however to create exceptions for scenarios specific to your application. There's plenty of good advice out there for exception handling -- take for example this MSDN exception design guidelines document for starters.
If you look at the .NET FW there are numerous Exceptions to specify certain conditions. IndexOutOfBoundsException, NotImplementedException, etc... They all exist and are derived from Exception to deal with exceptional (pun not intended) cases.
Drawing the line between what to classify as an Exception versus simply returning null for instance can often times become gray. Use your best judgement and try to remain constant within the team on that judgement.