Opened 13 years ago

Closed 13 years ago

Last modified 12 years ago

#416 closed enhancement (wontfix)

Make stock errors more usable programmatically

Reported by: Moritz Heidkamp Owned by:
Priority: minor Milestone: 4.9.0
Component: core libraries Version: 4.6.x
Keywords: Cc:
Estimated difficulty:

Description

If I call (with-input-from-file "foo" read) with foo being a non-existant file, I get the following exception:

condition: (exn i/o file)
 exn
        message: "cannot open file - No such file or directory"
        arguments: ("foo")
        location: open-input-file
 i/o
 file

The actual cause of this file i/o error was that the file didn't exist, however, only the error message containts this information. It would be nice if there was an additional property (maybe a symbol) that would allow for better programmatic handling of this other than the message itself (which is likely to change in future versions). This probably applies to other errors in the core, as well. This is mainly a suggestion. Any comments or better ideas?

Change History (11)

comment:1 Changed 13 years ago by Christian Kellermann

I am not sure what you want to do in case of this error. What I would do in a file selection dialog: catch the condition and present the message to the user and then try again.

What should a program do if the file does not exist? If I would expect a file to exist I would do a fstat call first anyhow, so I could create the file if necessary.

Unless there is a clear advantage in being able to tell the difference between file not found, file unreachable (network mounts), file unwritable (permissions or disk full?) and what not, I would like to dodge the issue at large.

comment:2 Changed 13 years ago by felix winkelmann

I agree with Peter that this may be more of a hassle than it initially seems. There are countless possible error situations and it might be better to explicitly test for those. Some basic context can be found from the condition-type (used in condition-case to dispatch to the different clauses). We could perhaps differentiate those somewhat (something like (exn i/o file nonexistant) for example). Would that be an acceptable compromise? Which situations should be distinguished then?

comment:3 Changed 13 years ago by sjamaan

ITYM Christian, not Peter :)

comment:4 Changed 13 years ago by sjamaan

More to the point: I agree with Moritz that it would be a useful thing to have more informative error objects. Christian's suggestion of first checking if the file exists is a workaround and opens up a race condition. In C, you have errno which you can check for the various conditions.

Maybe a simple way around this is adding the errno to the exception object, but that seems ugly and lazy :(

Exhaustively checking all possible errno values for each call isn't very elegant either, especially since you'd need lots of #ifdefs for various platforms since everyone adds their own error conditions to errno...

The compromise felix suggested sounds acceptable

comment:5 in reply to:  2 Changed 13 years ago by Moritz Heidkamp

Sure, further differentiating the condition is also a good solution, perhaps even cleaner than my suggestion. It's still a lot of hassle. Maybe I can look into it on some lazy sunday afternoon :-)

comment:6 in reply to:  4 ; Changed 13 years ago by Christian Kellermann

Replying to sjamaan:

More to the point: I agree with Moritz that it would be a useful thing to have more informative error objects. Christian's suggestion of first checking if the file exists is a workaround and opens up a race condition.

True, that's maybe a bad example and beside my main point.

Question is: How would programmers deal with it other than now?

To stick to Moritz's example, how does a more detailed condition type ease the situation? If your program assumes that the file is there and now it isn't what are you going to do? Fail silently or try to fix the situation hoping the user does not notice? And if you are to fix the situation silently, how does a better description help there?

In my eyes this will lead to awkward code where I do a call like this and then have lots of branches handling every condition I think I need. Makes it very similar to Java...

If adding another detailed condition type helps, go for it. I am not convinced (yet), but happy to hear how you think this helps. I do have an open mind...

comment:7 in reply to:  6 Changed 13 years ago by sjamaan

Replying to ckeen:

Question is: How would programmers deal with it other than now?

To stick to Moritz's example, how does a more detailed condition type ease the situation? If your program assumes that the file is there and now it isn't what are you going to do?

If it assumes that, it doesn't matter how the condition is structured :)

Fail silently or try to fix the situation hoping the user does not notice? And if you are to fix the situation silently, how does a better description help there?

You can only fix the situation by catching the relevant errors you know how to fix.

In my eyes this will lead to awkward code where I do a call like this and then have lots of branches handling every condition I think I need. Makes it very similar to Java...

Yeah, that would suck. But then, if you really need differing code for handling different situations, I don't see how else to solve it. It seems like a fundamental problem of wanting to deal with different situations differently.

If adding another detailed condition type helps, go for it. I am not convinced (yet), but happy to hear how you think this helps. I do have an open mind...

Yeah, I'm not sure this would really help. Maybe Moritz can explain how he wanted to use this in his code.

comment:8 Changed 13 years ago by felix winkelmann

Resolution: wontfix
Status: newclosed

This just leads to programming by accident. Try to avoid errors instead of using exception-handling as a substitution for control-flow.

comment:9 in reply to:  8 Changed 13 years ago by Moritz Heidkamp

Replying to felix:

This just leads to programming by accident. Try to avoid errors instead of using exception-handling as a substitution for control-flow.

Well, I think it's a question of how anal one is about certain kinds of problems. Say you have a program that can either load some cached state from a file if it exists or otherwise calculate it live. AFAIU your suggestion, one should do something like (when (file-exists? "cache") (set! state (with-input-from-file "cache" read-state))) and I would generally agree, mostly for stylistic reasons. However we now have introduced a race condition into our program: Should the file disappear between checking for its existence and reading it, it will fail although it could perfectly continue without loading the file. This means we would probably want to catch ENOENT errors but still fail on others (thus my initial request for more specific errors). If we do that though we don't really need the file-exists? call anymore, it is actually redundant with catching the error. Granted, this is a contrived example but I think it is an example of a more general class of problems. Feel free to disagree, of course, I'm not entirely committed to this either :-)

comment:10 Changed 13 years ago by felix winkelmann

Milestone: 4.7.04.8.0

Milestone 4.7.0 deleted

comment:11 Changed 12 years ago by felix winkelmann

Milestone: 4.8.04.9.0

Milestone 4.8.0 deleted

Note: See TracTickets for help on using tickets.