March 28, 2017
On Thursday, 23 March 2017 at 16:44:51 UTC, Jonathan M Davis wrote:
>
> Classes should not be implementing interfaces only to throw exceptions when they don't really want to be implementing some of the functionality of that interface. That's just plain bad design.
>

There are the cases, when NotImplementedException is the good choice, except for the pure Exception.
Currently, I am making the inter-server communication code. Now we have the situation, where there are many servers with different settings. So, in the master app I create 2 enums, say, MySettingsVariant, SlaveSettingsVariant. Then I'll rewrite the small piece of communication code, depends on their combinations. And the code will look like:

if (my == X && its == Y) {
} else if (my == Z && its == Y) {
} else {
    throw new NotImplementedException();
}

Well, when somebody will add a value in one of these enums and will forget to write something for the new combinations, he/she will get the meaningful stacktrace in the log. Well, I agree, it's very close to just throw Exception. The only difference in the name. But when I talked about NIE, I meant such cases in the first place (not the partial interface implementations as in some Java collections).

I just say. I don't persuade to add it to Phobos.
March 28, 2017
On Tuesday, 28 March 2017 at 08:29:44 UTC, Георгий wrote:
>
> I meant such cases in the first place

Well, I lie, I meant both.
March 28, 2017
On 3/25/2017 6:44 AM, Jacob Carlborg wrote:
> Talk about just providing a generic exception type. Take this error message,
> using std.file.copy:
>
> std.file.FileException@d.d(3354): /tmp/bar/foo.txt: Permission denied
>
> It doesn't tell if the failed permission is for the source or for the target. If
> failed to read or failed to write.


If you received an IOException instead, you're no better off. As Andrei observed, it is the message that's the problem, not the exception type.

In general, I think a lot of the issues you brought up are inadequate messages, or trying to solve the problem at the wrong level of the function call hierarchy (i.e. too far up).

In any case, trying to get good messages to the user is a never ending problem. No solution will be universal. It's actually a lot like writing portable code. People who have never ported code tend to make all the wrong choices in where to make things portable (see windows.h for 16 bit Windows). Crafting an exception hierarchy with no experience with nor clear idea of the problem one is trying to solve just creates a complex, useless mess. I fear that's the path we've gone down.

P.S. I've worked with trying to internationalize error messages. What a mess! The foreign language string tables tend to be written by people who knew the foreign language, but had little idea of the product domain. So the messages tended to be so bad/outdated/garbled that people would just prefer the English ones.

March 28, 2017
On 2017-03-28 11:25, Walter Bright wrote:

> If you received an IOException instead, you're no better off.

No, I agree. But I have not argued for or against a standardize exception hierarchy. I've argued that we need more specific error types (either as a hierarchy or flat structure).

> As Andrei observed, it is the message that's the problem, not the exception type.

It's an issue with both. It's an issue with the exception type because I cannot really handle the error in any sensible way. In my opinion the error message is more of a debug aid.

> In general, I think a lot of the issues you brought up are inadequate
> messages, or trying to solve the problem at the wrong level of the
> function call hierarchy (i.e. too far up).

void main()
{
    import std.stdio;

    try
        copy("/tmp/foo.txt", "/tmp/bar/foo.txt");
    catch (FileException e)
    {
        // handle permission error?
    }
}

How should I handle a permission error in the above example? It's not possible to do so without parsing the error message. This is catching the exception as close as possible to the source (without modifying Phobos).

> In any case, trying to get good messages to the user is a never ending
> problem. No solution will be universal. It's actually a lot like writing
> portable code. People who have never ported code tend to make all the
> wrong choices in where to make things portable (see windows.h for 16 bit
> Windows). Crafting an exception hierarchy with no experience with nor
> clear idea of the problem one is trying to solve just creates a complex,
> useless mess. I fear that's the path we've gone down.

Again, I have not argued for or against an exception hierarchy.

-- 
/Jacob Carlborg
March 28, 2017
On Tuesday, March 28, 2017 20:07:01 Jacob Carlborg via Digitalmars-d wrote:
> On 2017-03-28 11:25, Walter Bright wrote:
> > If you received an IOException instead, you're no better off.
>
> No, I agree. But I have not argued for or against a standardize exception hierarchy. I've argued that we need more specific error types (either as a hierarchy or flat structure).
>
> > As Andrei observed, it is the message that's the problem, not the exception type.
> It's an issue with both. It's an issue with the exception type because I cannot really handle the error in any sensible way. In my opinion the error message is more of a debug aid.

Agreed. Error messages are just for reporting what went wrong, not for being used to decide what the code should do. That depends on the exception type (assuming that it makes sense to respond based on the type of the error), or it depends on addition information that a specific exception type provides for the program to look at and use in order to figure out how to respond.

> > In general, I think a lot of the issues you brought up are inadequate messages, or trying to solve the problem at the wrong level of the function call hierarchy (i.e. too far up).
>
> void main()
> {
>      import std.stdio;
>
>      try
>          copy("/tmp/foo.txt", "/tmp/bar/foo.txt");
>      catch (FileException e)
>      {
>          // handle permission error?
>      }
> }
>
> How should I handle a permission error in the above example? It's not possible to do so without parsing the error message. This is catching the exception as close as possible to the source (without modifying Phobos).

And how would you ever handle a permission error? If you don't have the permissions for the file, you don't have permissions for the file. And trying to read a file that you don't have permissions for isn't really any different from if the file didn't exist. As far as I can tell, the only difference is in what you report to the user or log, and if that's the case, simply having a better error message is all that it makes sense to do. I expect that someone could come up with a case where knowing exactly what went wrong when trying to read or write a file could be dealt with programmatically if the program knew exactly what went wrong, but in most cases, it really doesn't matter. Either the operation succeeded, or it didn't. The why doesn't matter beyond reporting it to the user or logging it. The program is going to do the same thing regardless.

However, if you do want to respond to permission errors more specifically and do something differently with them than with other error cases, FileException _does_ have an errno member to get at the same information a C program would have. So, FileException is already providing additional benefit beyond what a plain Exception provides.

- Jonathan M Davis

March 29, 2017
On 2017-03-28 22:10, Jonathan M Davis via Digitalmars-d wrote:

> And how would you ever handle a permission error? If you don't have the
> permissions for the file, you don't have permissions for the file.

The application can ask for a password, i.e. "sudo". That is what TextMate is doing.

> And trying to read a file that you don't have permissions for isn't really any
> different from if the file didn't exist.

If the file doesn't exist the application can ask the user for another file (reading). If a directory doesn't exist it can ask the user if it should create the directory (writing a file), again, that is what TextMate is doing.

> As far as I can tell, the only
> difference is in what you report to the user or log, and if that's the case,
> simply having a better error message is all that it makes sense to do. I
> expect that someone could come up with a case where knowing exactly what
> went wrong when trying to read or write a file could be dealt with
> programmatically if the program knew exactly what went wrong, but in most
> cases, it really doesn't matter. Either the operation succeeded, or it
> didn't. The why doesn't matter beyond reporting it to the user or logging
> it. The program is going to do the same thing regardless.

But the standard library shouldn't decide that. It should just provide as much information as possible to let the developer of the application decide what to do with the error.

> However, if you do want to respond to permission errors more specifically
> and do something differently with them than with other error cases,
> FileException _does_ have an errno member to get at the same information a C
> program would have. So, FileException is already providing additional
> benefit beyond what a plain Exception provides.

Ok, I apologize for not look at exactly what FileException contains. Although I still think it's the wrong way of providing that information. In my opinion it should be it's own exception type, otherwise I would need to catch _all_ FileException exceptions even though I cannot handle them. Then look at the errno code to check if I can handle it and otherwise rethrow the exception.

In addition to that I think that error originate from a call to a C function, indicated by the presence of "errno", is an implementation detail which should not be exposed outside of Phobos. It's also slightly awkward from a Windows point of view that the Unix name "errno" is used for the field. On Windows it's actually "GetLastError" that is used to populate the "errno" field not the "errno" function.

It's missing a source and target field (in the case of "copy"). I don't know which files failed, and based on the error message I don't even know if it was the source or target that failed. It wouldn't be right either to add those fields to FileException because not all operations have a source and target. Yet again it shows that we need more specific exception types.

In my opinion the following information should be available in the exception type for an exception to due a failed copy operation, either as a field or in the type itself:

* file and line number - where the exception originated
* message - generic error message for debug aid and the most simple form of error handling
* source and target - the resources (file/directory) that were involved in the operation
* failed resource - somehow indicating if it was the source or target that failed
* operation - that operation that failed, "copy" in this case
* error - what actually went wrong, "permission denied" in this case

-- 
/Jacob Carlborg
1 2 3 4 5
Next ›   Last »