The Exception is a convenient container, that is tempting to use for various purposes. But is it OK to use it for handling legal states in your code?
My example: I have a geometric function that finds the closest object within a search radius:
public IPoint FindNearest(IPoint origin, double searchRadius)
{
}
My idea was that I could throw an exception, when the search doesn't find a hit. But is this a good idea? Alternatively, I could return Null (which I don't like), or return a result object instead of a Point.
Exception, in general, represents an invalid or "exceptional" scenario. In your case, if not finding a hit is an exceptional scenario and it should always be found in usual cases then you can throw exception.
You should always try to avoid throwing exception because of its heavy nature. If caller code is calling this method frequently and your method is in result throwing lot of exceptions, it will make your program slow
Best practice is to use exception only if you can not handle the error in a functial way. In this case not finding a location and returning null is best, because your calling function can handle the null in a functional way. Besides the clean code, throwing and handling exceptions is realy bad for performance, so use them only as last resort.
You could do something like
public bool TryFindNearest(IPoint origin, double searchRadius, out IPoint result)
{
// your logic here, return true if you find a point. Otherwise return false.
}
Then your calling code can do something like:
IPoint nearestPoint;
If (TryFindNearest(origin, searchRadius, out nearestPoint))
{
// do your stuff.
}
Exceptions should be used in invalid scenarios not to control program flow.
Usually in this situation throwing exceptions isn't a good idea, they are expensive and semantically mean something else entirely.
You could return null and do a null check, or I occasionally find that using the Special Case pattern works out nicely and makes for readable code if you give the class/interface a sensible name.
In this instance, you'd return either an implementing class or derived interface called something like:
public class NoHitOnRadius : IPoint {}
And return that from the call when you get no hits. Then the calling code checks the return type:
var p = FindNearest(...);
if (p is NoHitOnRadius)
{
// Do something.
}
Although in this specific situation I'd likely go with the TryFindNearest semantics (to keep commonality with the likes of TryParse etc) that RobH suggests.
Related
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.
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.
I recenly encountered this problem in a project: There's a chain of nested objects, e.g.: class A contains an instance variable of class B, which in turns has an instance variable of class C, ..., until we have a node in the tree of class Z.
----- ----- ----- ----- -----
| A | ---> | B | ---> | C | ---> | D | ---> ... ---> | Z |
----- ----- ----- ----- -----
Each class provides getters and setters for its members. The parent A instance is created by an XML parser, and it is legal for any object in the chain to be null.
Now imagine that at a certain point in the application, we have a reference to an A instance, and only if it contains a Z object, we must invoke a method on it. Using regular checks, we get this code:
A parentObject;
if(parentObject.getB() != null &&
parentObject.getB().getC() != null &&
parentObject.getB().getC().getD() != null &&
parentObject.getB().getC().getD().getE() != null &&
...
parentObject.getB().getC().getD().getE().get...getZ() != null){
parentObject.getB().getC().getD().getE().get...getZ().doSomething();
}
I know that exceptions should not be used for ordinary control flow, but instead of the previous code, I have seen some programmers doing this:
try {
parentObject.getB().getC().getD().getE().get...getZ().doSomething();
} catch (NullPointerException e){}
The problem with this code is that it may be confuse when maintaining it, since it doesn't show clearly which objects are allowed to be null. But on the other hand is much more concise and less "telescopic".
Is it an acceptable to do this to save development time?
How could the API be redesigned to avoid this problem?
The only thing I can think of to avoid the long null checking is to provide void instances of the nested objects and providing isValid methods for each one of them, but wouldn't this create a lot of innecesary objects in memory?
(I've used Java code, but the same question can apply to C# properties)
Thanks.
It is bad design if parentObject needs to know that A contains a B which contains a C wich contains.... That way, everything is coupled to everything. You should have a look at the law of demeter: http://en.wikipedia.org/wiki/Law_Of_Demeter
parentObject should only call methods on its instance variable B. So, B should provide a method that allows for the decision, e.g.
public class A {
private B myB;
//...
public boolean isItValidToDoSomething(){
if(myB!=null){
return myB.isItValidToDoSomething();
}else{
return false;
}
}
}
Eventually, at the level of Z, the method has to return true.
Imho, saving development time is never a reason for tolerating problems in the design. Sooner or later these problems will steal you more time than it would have taken to fix the problems in the first place
It's bad practice to use Exceptions here.
There's a hint in the name: Exceptions are for exceptional circumstances (i.e. unexpected) . If nulls are expected values, then encountering them is not exceptional.
Instead, I'd have a look at the class hierarchy and try to understand why such deep access chaining needs to happen. This seems like a big design issue, you shouldn't normally expect the caller to construct calls using deep knowledge of the structure of objects hidden within class A.
Questions you could ask:
Why does the caller need to doSomething() with the Z object anyway? Why not put the doSomething() on class A? This could propagate doSomething() down the chain if needed and if the relevant field was not null....
What does a null mean if it exists in this chain? The meaning of a null will suggest what business logic should be employed to handle it.... which could be different at each level.
Overall, I suspect the right answer is to put doSomething() on each level of the heirarchy and have the implementation something like:
class A {
...
public void doSomething() {
B b=getB();
if (b!=null) {
b.doSomething();
} else {
// do default action in case of null B value
}
}
}
If you do this, then the API user only has to call a.doSomething(), and you have the added bonus that you can specify different default actions for a null value at each level.
Personally I like to avoid this problem altogether by using an option type. By adjusting the value returned from these methods/properties to be Option<T> rather than T the caller can choose how they wish to handle the case of no value.
An option type can either have a contained value or not (but the option itself can never be null), but the caller cannot simply pass it on without unwrapping the value so it forces the caller to deal with the fact there may be no value.
E.g. in C#:
class A {
Option<B> B { get { return this.optB; } }
}
class B {
Option<C> C { get { return this.optC; } }
}
// and so on
If the caller wants to throw, they merely retrieve the value without explicitly checking to see if there is one:
A a = GetOne();
D d = a.Value.B.Value.C.Value.D.Value; // Value() will throw if there is no value
If the caller wants to just default if any step doesn't have a value, they can perform mapping/binding/projection:
A a = GetOne();
D d = a.Convert(a => a.B) // gives the value or empty Option<B>
.Convert(b => b.C) // gives value or empty Option<C>
.Convert(c => c.D) // gives value or empty Option<D>
.ValueOrDefault(new D("No value")); // get a default if anything was empty
If the caller wants to default at each stage, they can:
A a = GetOne();
D d = a.ValueOrDefault(defaultA)
.B.ValueOrDefault(defaultB)
.C.ValueOrDefault(defaultC)
.D.ValueOrDefault(defaultD);
Option is not currently part of C# but I imagine one day will be. You can get an implementation by referencing the F# libraries or you may be able to find an implementation on the web. If you'd like mine, let me know and I'll send it to you.
Well, it depends on exactly what you're doing in the catch. In the above case, it appears that you want to call doSomething() if it's available, but if it isn't you don't care. In this case I would say that trapping the specific exception you're after is just as acceptable as a verbose check to ensure you won't throw one to begin with. There are many "null-safe" methods and extensions that use try-catch in a very similar manner to what you propose; "ValueOrDefault"-type methods are very powerful wrappers for exactly what's been done with the try-catch, for exactly the reason try-catch was used.
Try/catch is, by definition, a program flow control statement. Therefore, it is expected to be used to "control ordinary program flow"; I think the distinction you are trying to make is that it should not be used to control the "happy path" of normal error-free logic flow. Even then I might disagree; there are methods in the .NET Framework and in third-party libraries that either return the desired result or throw an exception. An "exception" is not an "error" until you cannot continue because of it; if there's something else you can try or some default case the situation can boil down to, it can be considered "normal" to receive an exception. So, catch-handle-continue is a perfectly valid use of try-catch, and many uses of exception throwing in the Framework expect you to handle them robustly.
What you want to avoid is using try/catch as a "goto", by throwing exceptions that aren't really exceptions in order to "jump" to the catch statement once some condition is satisfied. This is definitely a hack, and thus bad programming.
The problem with the "catch an exception" approach is that it seems a bit heavy-handed. The exception stack trace should show you where it failed since your method names make it quite clear where you are in the hierarchy but it is not a good way of going about it. Plus how would you recover from the exception and carry on to a good state of your code?
If you must keep this very deep hierarchy then you could use static instances of each object which defines an "empty" state. The best example I can think of which does this is the C# string class which has a static string.Empty field. Then each call of getB(), getC() ... getZ() would return either a real value or the "empty" state, allowing you to chain the method calls.
By making the "empty" state instances static there would only be one of each type in your system. But you would need to consider what an "empty" state looks like for each type in your hierarchy and make sure it doesn't affect any other part of your application inadvertently.
In Python, they encourage the style of "easier to ask forgiveness than permission", which could be applied here to say that it's better to just optimistically try to get to Z without safety checking, and let the exception handler fix a miss. That's easier to code, and it's more performant if the call of Z not being in the call chain is less likely than the case that it will be.
Aside from violating a bunch of OOP good design principles and exposing deeply nested private members, this code also seems vaguely dynamic in nature. That is, you want to call method X but only if X exists on the object, and you want that logic to apply to all objects in a hierarchy of unknown length. And you can't change the design because this is what your XML translation gives you.
Can you change languages then? Statically-typed C# may not be the best choice for what you're doing here. Maybe using Iron Python or some other language that's a little looser on typing will let you more easily manipulate your DOM. Once you've got the data in a stable state, you can pass that off to C# for the rest.
Using exceptions seem a poor fit here. What if one of the getters contained non-trivial logic, and threw a NullPointerException? Your code would swallow that exception without intending to. On a related note, your code samples exhibit different behaviour if parentObject is null.
Also, there really is no need to "telescope":
public Z findZ(A a) {
if (a == null) return null;
B b = a.getB();
if (b == null) return null;
C c = b.getC();
if (c == null) return null;
D d = c.getD();
if (d == null) return null;
return d.getZ();
}
I think you could provide static isValid methods on each class, for example for class A that would be:
public class A {
...
public static boolean isValid (A obj) {
return obj != null && B.isValid(obj.getB());
}
...
}
And so on. Then you would have:
A parentObject;
if (A.isValid(parentObject)) {
// whatever
}
However, although I won't get into you business I must say that such a method chaining does not say anything good about the design; maybe it's a sign of need for refactoring.
I agree with the other answers that this should not need to be done, but if you must here is an option:
You could create an enumerator method once such as:
public IEnumerable<type> GetSubProperties(ClassA A)
{
yield return A;
yield return A.B;
yield return A.B.C;
...
yield return A.B.C...Z;
}
And then use it like:
var subProperties = GetSubProperties(parentObject);
if(SubProperties.All(p => p != null))
{
SubProperties.Last().DoSomething();
}
The enumerator will be lazily evaluated leading to no exceptions.
I have a Result object that lets me pass around a List of event messages and I can check whether an action was successful or not.
I've realized I've written this code in alot of places
Result result;
try
{
//Do Something
...
//New result is automatically a success for not having any errors in it
result = new Result();
}
catch (Exception exception)
{
//Extension method that returns a Result from the exception
result = exception.ToResult();
}
if(result.Success) ....
What I'm considering is replacing this usage with
public static Result CatchException(Action action)
{
try
{
action();
return new Result();
}
catch (Exception exception)
{
return exception.ToResult();
}
}
And then use it like
var result = Result.CatchException(() => _model.Save(something));
Does anyone feel there's anything wrong with this or that I'm trading reusability for obscurity?
Edit: The reason I am trapping all exceptions is I use this code inside of my ViewPresenter classes at any point I interact with my model since if I get an unhandled exception I'd rather display the actual error to the user (internal app) as opposed to just redirecting them the generic error page.
I don't think there is anything wrong with using a functional approach, and passing in a lambda. That is perfectly valid.
That being said, I'd question your use in this specific scenario. Trapping all exceptions into a general purpose "Result" class seems dangerous. Ideally, you should be catching exceptions which you can handle correctly - not every possible exception and continuing.
That being said, if you really want to do this, I have a couple of suggestions for you:
1) I'd make a static, immutable result for success, and just do:
result = result.Success;
This avoids generating a new "success" each time you succeed, which hopefully is the most common option.
2) I'd probably avoid the extension method, and do:
result = new Result(exception);
This will be much more clear and obvious in intent, and there's really no reason to do an extension method in this case...
You shouldn't be catching Exception like this. You should only be catching known exception types that you know how to handle.
If you did that, you code would no longer be so repetitive, so there would be no case for using this pattern for re-usability.
All round this looks like a very bad idea, not just the lambda pattern, I'm talking about the handling of exceptions by converting them into results objects. You are basically allowing yourself to ignore all exceptions and continue working. There is a reason why C# error handling is done with exceptions and not with return codes, and that is because exceptions allow for structured, hierarchical and call stack based handling. Unless you have simplified the code for this question, I would reconsider your exception handling process.
In general though, I don't see anything wrong with the lambda pattern. I use something similar myself for wrapping multiple retries of a code block. But in this case I don't think it's what you need.
If you feel the need to write such an automated exception handler system you may be over-using exceptions, which could have serious performance implications.
However, this appears to be a generic system for converting exceptions into error codes - so why not just use error codes in the first place? Or learn to use exceptions more effectively so you don't feel the need to convert them into error codes? The fact that you are trying to convert them to something else should raise alarms and suggest to you that you're missing the point somewhere.
I was digging around in MSDN and found this article which had one interesting bit of advice: Do not have public members that can either throw or not throw exceptions based on some option.
For example:
Uri ParseUri(string uriValue, bool throwOnError)
Now of course I can see that in 99% of cases this would be horrible, but is its occasional use justified?
One case I have seen it used is with an "AllowEmpty" parameter when accessing data in the database or a configuration file. For example:
object LoadConfigSetting(string key, bool allowEmpty);
In this case, the alternative would be to return null. But then the calling code would be littered with null references check. (And the method would also preclude the ability to actually allow null as a specifically configurable value, if you were so inclined).
What are your thoughts? Why would this be a big problem?
I think it's definitely a bad idea to have a throw / no throw decision be based off of a boolean. Namely because it requires developers looking at a piece of code to have a functional knowledge of the API to determine what the boolean means. This is bad on it's own but when it changes the underlying error handling it can make it very easy for developers to make mistakes while reading code.
It would be much better and more readable to have 2 APIs in this case.
Uri ParseUriOrThrow(string value);
bool TryParseUri(string value, out Uri uri);
In this case it's 100% clear what these APIs do.
Article on why booleans are bad as parameters: http://blogs.msdn.com/jaredpar/archive/2007/01/23/boolean-parameters.aspx
It's usually best to choose one error handling mechanism and stick with it consistently. Allowing this sort of flip-flop code can't really improve the life of developers.
In the above example, what happens if parsing fails and throwOnError is false? Now the user has to guess if NULL if going to be returned, or god knows...
True there's an ongoing debate between exceptions and return values as the better error handling method, but I'm pretty certain there's a consensus about being consistent and sticking with whatever choice you make. The API can't surprise its users and error handling should be part of the interface, and be as clearly defined as the interface.
It's kind of nasty from a readabilty standpoint. Developers tend to expect every method to throw an exception, and if they want to ignore the exception, they'll catch it themselves. With the 'boolean flag' approach, every single method needs to implement this exception-inhibiting semantic.
However, I think the MSDN article is strictly referring to 'throwOnError' flags. In these cases either the error is ignored inside the method itself (bad, as it's hidden) or some kind of null/error object is returned (bad, because you're not using exceptions to handle the error, which is inconsistent and itself error-prone).
Whereas your example seems fine to me. An exception indicates a failure of the method to perform its duty - there is no return value. However the 'allowEmpty' flag changes the semantics of the method - so what would have been an exception ('Empty value') is now expected and legal. Plus, if you had thrown an exception, you wouldn't easily be able to return the config data. So it seems OK in this case.
In any public API it is really a bad idea to have two ways to check for a faulty condition because then it becomes non-obvious what will happen if the error occurs. Just by looking at the code will not help. You have to understand the semantics of the flag parameter (and nothing prevents it from being an expression).
If checking for null is not an option, and if I need to recover from this specific failure, I prefer to create a specific exception so that I can catch it later and handle it appropriately. In any other case I throw a general exception.
Another example in line with this could be set of TryParse methods on some of the value types
bool DateTime.TryParse(string text, out DateTime)
Having a donTThrowException parameter defeats the whole point of exceptions (in any language). If the calling code wants to have:
public static void Main()
{
FileStream myFile = File.Open("NonExistent.txt", FileMode.Open, FileAccess.Read);
}
they're welcome to (C# doesn't even have checked exceptions). In Java the same thing would be accomplished with:
public static void main(String[] args) throws FileNotFoundException
{
FileInputStream fs = new FileInputStream("NonExistent.txt");
}
Either way, it's the caller's job to decide how to handle (or not) the exception, not the callee's.
In the linked to article there is a note that Exceptions should not be used for flow of control - which seems to be implied in the example questsions. Exceptions should reflect Method level failure. To have a signature that it is OK to throw an Error seems like the design is not thought out.
Jeffrey Richters book CLR via C# points out - "you should throw an exception when the method cannot complete its task as indicated by its name".
His book also pointed out a very common error. People tend to write code to catch everything (his words "A ubiquitous mistake of developers who have not been properly trained on the proper use of exceptions tend to use catch blocks too often and improperly. When you catch an exception, you're stating that you expected this exception, you understand why it occurred, and you know how to deal with it.")
That has made me try to code for exceptions that I can expect and can handle in my logic otherwise it should be an error.
Validate your arguments and prevent the exceptions, and only catch what you can handle.
I would aver that it's often useful to have a parameter which indicates whether a failure should cause an exception or simply return an error indication, since such a parameters can be easily passed from an outer routine to an inner one. Consider something like:
Byte[] ReadPacket(bool DontThrowIfNone) // Documented as returning null if none
{
int len = ReadByte(DontThrowIfNone); // Documented as returning -1 if nothing
if (len
If something like a TimeoutException while reading the data should cause an exception, such exception should be thrown within the ReadByte() or ReadMultiBytesbytes(). If, however, such a lack of data should be considered normal, then the ReadByte() or ReadMultiBytesbytes() routine should not throw an exception. If one simply used the do/try pattern, a the ReadPacket and TryReadPacket routines would need to have almost identical code, but with one using Read* methods and the other using TryRead* methods. Icky.
It may be better to use an enumeration rather than a boolean.