-
-
Notifications
You must be signed in to change notification settings - Fork 704
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Consolidate / clean up exception types used for OS exceptions #2616
Conversation
FileException is now an alias of OSException. Related changes: - Removed some redundant stat calls - Improved copy's exception text on Windows
4d5cebd
to
ca64734
Compare
| // For FileException compatibility. | ||
| alias errno = code; | ||
|
|
||
| this(uint code, string msg, string file = null, size_t line = 0) @trusted |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
null and 0 instead of __FILE__ and __LINE__? Was this discussed recently?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No idea what's going on here. Maybe this predates these having proper values as value argument defaults.
|
By the looks of it, Further, the whole one-exception-type-per-module setup is bonkers anyway, so I'm also for just consolidating them into the same type which this patch also does, but this might be a point of contention. The one-exception-type-per-module setup has supporters, so now would probably be a good time to come out of the woodwork and argue its case. If this setup has any merit, then this patch is a fairly serious silent breaking change. |
|
Exception types should be based on what makes sense to catch. So, for instance, if it makes sense to differentiate between exceptions that occurred specifically when operating on a file vs another kind of OS error, then it makes sense to have both Regardless, I don't think that having an exception type per module really makes sense, and I think that most of us have agreed on that in the past. It's just that we never necessarily agreed on what the exception hierarchy really should look like, and even where we did, no one took the time to implement it. But what exceptions you have is all about needing to catch and handle exceptions differently based on what they're for, not based on which module they're it. Sometimes, that falls along module boundaries, but it often doesn't. I'll probably have to look these over too see whether I agree that they should all be consolidated into a single exception type, but I agree that it at least makes sense to have a common base type for all of the OS-based exceptions. It's just a question of whether having exception types derived for that for specific situations makes sense or not - either based on needing to catch them separately or on there being additional information necessary for a particular exception (and therefore more member variables). But module-based exceptions really doesn't make much sense IMHO. |
|
I've tried to avoid breaking changes as much as was reasonable. Here's the remaining breaking changes:
|
|
DIP33 deserves a mention here. In general I like the suggestions in this DIP, and this PR basically implements the "SystemException, ErrnoException, WinAPIException" part of it. I don't have time to take a closer look at it right now, but a cursory look suggests that there are several issues consolidating it with this PR, notably that it suggests both a Of course, redesigning the Phobos exception hiearchy is probably a bit beyond the scope of this PR, so I guess we should focus on forwards-compatibility with any future redesign. |
|
I discovered a breaking change in my own code (yay for dogfooding): User code might instantiate I guess I should change There's still the question of what deprecation path (if any) should be used for the old exception aliases. |
|
|
|
So there are some breaking changes. What are the wins that justify them? |
|
Cleaning up the mess with platform-specific exceptions. All of this kind of bobbled up when Windows code was fixed to use GetLastError (and wenforce) instead of wrongly relying on errorno. Then it turned out that FileException was tied to cenforce so we traded one problem for another. So the proper solution is to have nice, platform independant exceptions. |
That's not possible. "File exceptions" can be caused by:
I recall that this was discussed when DIP33 was proposed. There's some issues with the enum-based approach, such as not being able to catch only certain types of errors as indicated by the enum, and (because there is no subclassing) potentially breaking code that was checking for
If you mean my last comment, I intend to fix those in my next pass over the code (probably when we decide the deprecation path). If you mean the minor ones listed in my first comment, I elaborated on the reasons for the change in the linked issue. |
|
As a sidenote, I really wish we could construct the exception's |
Well, I think that it's a serious negative if you can't catch a This proposal makes it so that the specific exception type - I don't know how well we can fix this without breaking code, but IMHO what you're suggesting isn't much better than just making everything throw |
This PR fixes implementation, not user-facing design. DIP33 was meant to fix design. The WindowsException and ErrnoException classes are distinct because their implementation is distinct (in how they interpret the error code). Users should not catch WindowsException or ErrnoException. All documentation that throws either of those must mention OSException. I think this is the wrong place to seriously discuss proposals which dramatically change the user-facing design, such as the enum proposal. There are numerous ambiguous questions such as what members the enum should have, or questions such as: "If process creation fails because the indicated file was not found, is it a FileException or a ProcessException? And if we have a FileNotFoundException, it has to be a subclass of FileException even though the failing function was in std.process, not std.file."
I'd like to contest this point of view. OS operations, on files or otherwise, can fail due to a multitude of reasons. The documentation of any API or C call has a list of failure reasons and associated error codes. A FileException by itself is thus of very limited use. Any effective exception recovery for file operations requires wrapping a very small amount of code in a try block (usually a single function call). I agree that it would be useful to e.g. try deleting a file that might exist, and silently catch an exception indicating the file did not exist, and letting all others propagate. I don't see a good way to do it either. But I'm sure all this was already discussed along with DIP33. |
|
Time to rebase. We NEED platform-agonstic exceptions in std lib no 2 thoughts about it. |
|
I think a I have good idea of 2nd iteration on DIP 33 that uses Interfaces instead of enums, will try to compose sometime soon. |
|
Does anyone have any thoughts on the deprecation path for the old exception classes? It's the only remaining open question regarding the contents of this patch. TODO:
|
|
Merge conflicts, please rebase, thanks! |
|
Why? It's not ready to merge even ignoring conflicts. |
|
Nevermind, got mixed up with another PR. |
If |
|
Because the error code changes meaning depending on where it comes from. There needs to be a way to distinguish errno codes from GetLastError ones, whether through inheritance or otherwise. |
This is wrong on "pretty much the entire reason" line. The reason (as usual) to have different types is because the implementation is very different. And the connection between them is that they represent the same kind of thing - operating system exception, so there is little need to catch them explicitly (unless deliberately staying unportable) rather then by portable alias (or super type). |
|
Ping. Any progress on this? |
|
ping |
|
Do we need consensus or can I just fix up the remaining issues myself and someone will merge? |
|
Well, I just wanted to get the discussion going again, I didn't participate too much in the discussion so I don't know if it's merge-ready, just that it's stopped for too long. :-P Dmitry did propose on the forum to support catching by interface, then it would address people's concerns about wanting to catch exceptions by meaningful types as opposed to implementation-specific types. |
|
I'm going to have to revisit this subject in more depth, then. |
|
closing for now, @CyberShadow please reopen when you're on this |
|
I would appreciate if someone familiar with Phobos could take over this, currently I would prefer to spend time on improving dlang.org and the forum rather than debating exception hierarchies. |
https://issues.dlang.org/show_bug.cgi?id=13620