When your method fails, but succeeds ... Would you return failure or success?

I doubt that there is a definite answer, but I am interested in different opinions on this issue. Thus, the Communite wiki.

You are developing a method. This serves the purpose, so you design it first. The caller uses your method, and the method fails, but, and now, the final goal, which tempts the existence of the method, nevertheless is achieved - thanks to external circumstances that you are not under your control or some kind of magic, you choose. Could you report this situation to the caller as failure or success?

We choose a trivial example. You are writing the DeleteFile function. It takes a file path and deletes the file. Someone calls this function by providing a path. The function looks up the file, but it does not exist. This is not a permissions problem or anything else, the file is really missing. Perhaps another process deleted it a microsecond ago, and perhaps it did not exist at all. The function did not complete its task, so it should report an error ... but the only reason the user should call this function is to make sure that the file does not exist, and voila, it is not, therefore it is a success .

I expect such answers to be “just more verbose in your return values”, and I’m happy to return a detailed result in the form of free information, but what (and why) would you return, success or failure as the main flag of success? Will it be FALSE with the additional flag BUT_DOES_NOT_EXIST_ANYWAY, or will it be TRUE with the flag BUT_THANK_SOMEONE_ELSE?

EDIT

Please do not give answers that apply only to the example above. I ask about the situation as a whole, including when the method has no parameters, or for the wrong reason, it cannot be called for another reason.

+4
source share
6 answers

When new programmers learn to write functions, the terms prerequisites and postconditions are often introduced. Prerequisites are assumptions that must be met in order for your method to work correctly. Postconditions are guarantees that your method makes the system state after execution.

I think that a reasonable prerequisite for calling the deleteFile method is that the file currently exists. If the preconditions are not met, the method should fail , even if the postconditions were reached by a random, workaround.

Now, if your method was called by deleteFileIfExists , this is a different story. You have not imposed such strict prerequisites on the method.

+13
source

Follow the principle of least surprise and throw an exception.

I think about this: if I wrote code and included an error in my code that passed the wrong path to the DeleteFile function, the path is so wrong that it never existed, I would expect the DeleteFile to be thrown to indicate what I did something is wrong.

If you want, you can create an overload that takes a parameter called ThrowOnFileNotExist or something like that, and if it is set to false, this will not affect this situation. But I think this will be a rare violation case.

+7
source

What are the exceptions for?

throw new FileDoesNotExistException

+4
source

If you intend to fail and succeed, what have you done?

I think the client should decide what to do. If your function is prompted to delete a file that does not exist, throw an exception. Then the client can catch this exception and decide that the file does not exist or it was successfully deleted, the end result is the same, and it can run normally.

Alternatively, if the missing file is an expected feature, that is, is not exceptional, you can simply return a failure status that the caller can ignore. This again leaves the solution to the client.

In any case, if you follow the principle that a function should do one thing and do it well, the client can group the function calls in any suitable way for the task, and success or failure becomes much finer.

What you should not do is return success if the function did not complete successfully. It doesn’t matter if the end result is the same. This is crazy.

+3
source

Your example is ideal for a triple boolean: True / False / FileNotFound .

 enum Bool { True, False, FileNotFound }; 

UPDATE
Everyone jokes aside. If the method cannot perform this function, then it must have a return code (or exception) appropriate to the situation. It does not matter for the method if the end result is the same; although this may call the caller of this method.

I prefer to avoid throwing exceptions and storing return codes instead. IMHO exception types exist for situations that the code cannot handle. Your sample method is small enough to just return False enough. To determine why, a call code must be specified.

There are many reasons why a simple method, such as DeleteFile, may fail. The file does not exist, you do not have security rights, the file is locked, the file system is delayed, etc. Each of them must have its own return code.

Then it is up to the calling code to decide that "oh the file does not exist, it doesn't matter." Or: "What do you mean that I have no rights ?!" Stop it !! "

Point: Do not return true if the method really cannot be executed.

+1
source

The function should throw an exception (or return a failure value, whatever). the user should probably see success.

IOW, programmers calling the function must know the truth. But what the user interface represents for the user is more likely dependent on the overall functionality, and I assume that the target user.

To take the “delete file” example - under normal circumstances, I expect your application to simply delete the file from the list or something else will go over — let the user see that the file has been deleted; they probably don't care how that happened.

("under normal circumstances" because in some applications this may be important.)

0
source

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


All Articles