.NET return value against thrown exception question

Suppose we have a method for processing operations in a hierarchical data structure of a tree located in a class that processes such a structure.

Get closer to one of these methods:

void MoveNode(Node currentNode, Node newParentNode) { /* check if new parent isn't current child already */ if (newParentNode.LMargin < currentNode.LMargin && newParentNode.RMargin > currentNode.RMargin) { //DO WORK } else throw new ArgumentException("New parent node cannot be current own child"); } 

MSDN Status: Do not throw exceptions to control flow!

My question is : is this, in your opinion, using ArgumentException, or would you use some kind of return value. If so, how would you send the error / validation message.

+4
source share
4 answers

Since the generated exception indicates an error here, and therefore it will never be selected in the correct work program, and the exception is the right choice.

What you should not do:

 try { MoveNode(...) //Do something } catch(ArgumentException e) { //Do something else } 

In this example, you expect the exception to be thrown regularly and use it to control the flow of control. Finding an ArgumentException in the caller is almost always a bad idea. Such an exception should only be detected in the top-level handler, if at all.

Personally, I don't like that you throw an exception in the else clause. I prefer to check the parameters at the beginning of the function and immediately throw an exception. This prevents embedding the error-free error code in multiple if blocks.

There are three types of exceptions.

  • Asynchronous exception like StackOverflow, OutOfMemory and ThreadAborted. They can occur anywhere and cannot be processed.
  • Error exceptions, such as ArgumentException, write them to the top-level handler and fix the error.
  • Expected exceptions that indicate an error that may be handled locally. You usually use them when errors are rare, and you cannot know in advance that the operation will lead to an error. I / O errors are a typical example of this.
    The reason is usually external. For example, an inaccessible file, a network failure, or invalid data in the file you are trying to analyze.

Eric Lippert Talks About These Kinds of Exceptions in a Blog Entry: Vexing Exceptions

When to use the third type of exception and when to use return values ​​is a court call.

+10
source

If this is an unexpected runtime error, as here, this is an exception, otherwise it should be a return value. Model your solution using int.Parse (throws) /int.TryParse (return value), the first for circumstances when you know things should be int (parsing a typed structure, for example), the other for checking user input (input errors expected from the user).

Exception handling is an expensive runtime on a throw, and should be avoided in a loop.

+1
source

Instead of asking if something needs to return a value or throw an exception, you need to ask what function it promises to do. If the function promises to move a node, it should throw an exception if it cannot. If the promises function moves a node, if possible, or indicates through the return value that it cannot be moved, but only throws an exception, if the data structure is fundamentally corrupt in some way than is implied in the ability to move the node, it should do it . Sometimes it is useful to provide functions like β€œdo it” and β€œtry”.

Regarding the type of exception for the throw, I frankly do not like the concept of throwing most of the built-in types of exceptions from the user code, since there is no good programmatic way to determine if there was an ArgumentException exception from your routine or from some ordinary one that was called by your procedure, and most exceptions say nothing about the quality of the underlying data structure.

If you try, for example, to parse a file from disk and integrate it with an existing data structure and throw an exception, it does not matter if there was an ArgumentException or a SubscriptOutOfBoundsException or a DiskReadErrorException or something else. Most importantly, whether the parsing attempt was discarded in such a way as to leave the data structure reliable; Of secondary importance is whether it will be possible to parse the file differently or under other circumstances. The type of exception really matters only to the extent that it can answer these first two questions.

+1
source

I do not think this is a case of "do not use an exception to control the flow."

This is a confirmation of the argument. The method cannot work, the input parameters are invalid, so using an exception is the best way to tell the caller that he is trying to do bad business.

0
source

Source: https://habr.com/ru/post/1338228/


All Articles