Skip to content
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

Separate SystemError from SysError #9737

Merged
merged 1 commit into from
Jan 12, 2024

Conversation

Ericson2314
Copy link
Member

@Ericson2314 Ericson2314 commented Jan 11, 2024

Motivation

Most of this is a catch SysError -> catch SystemError sed. This is a rather pure-churn change I would like to get out of the way. The intersting part is src/libutil/error.hh.

On Unix, we will only throw the SysError concrete class, which has the same constructors that SystemError used to have.

On Windows, we will throw WinError and SysError. WinError (which will be created in a later PR), will use a DWORD instead of int error value, and GetLastError(), which is the Windows equivalent of the errno machinery. Windows will also use SysError because Window's "libc" (MSVCRT) implements the POSIX interface, and we use it too.

As the docs describe, while we throw one of the 3 choices above (2 concrete classes or the alias), we should always catch SystemError. This ensures no matter how the implementation changes for Windows (e.g. between SysError and WinError) the catching logic stays the same and stays correct

Context

#8901 will take advantage of this.

Priorities and Process

Add 👍 to pull requests you find important.

The Nix maintainer team uses a GitHub project board to schedule and track reviews.

CC @wegank

@github-actions github-actions bot added new-cli Relating to the "nix" command store Issues and pull requests concerning the Nix store repl The Read Eval Print Loop, "nix repl" command and debugger labels Jan 11, 2024
@Ericson2314 Ericson2314 force-pushed the sys-error-split branch 2 times, most recently from 4332d69 to 5f2fa37 Compare January 11, 2024 02:15
@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/nix-on-windows/1113/100

Comment on lines 217 to 198
/**
* A "portable" error number.
*
* It has to be big enough for all platforms:
*
* - Unix: `int` (perhaps `int32_t`)
* - Windows: `DWORD` (which is `uint32_t`)
*
* The smallest type which contains all values of both types is
* `int64_t`.
*/
using ErrorNumber = int64_t;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this really make sense? I imagine that the same error code will mean something totally different depending on whether it's a Posix error code or a Windows one. So what are the cases where it makes sense to introspect the errNo of an arbitrary SysError instance (without knowing whether it's a Posix or Windows one?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You right, there will be some now-incorrect (on windows) code inspecting this. Either we need to added a bunch of OS-conditional constants for the comparisons, or we need to push the number into each subclass and create a bunch of virtual methods.

I can do one of those two up-front, but we could also just file an issue 😅. It won't make the Unix version less correct, and I'll be focused on just getting Windows to build at all for the next few PRs before worrying about Windows working correctly.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldn't have to be exposed on the superclass of the platform-specific errors.

If platform-generic code needs to know something based on those codes, I don't think that happens very often, so you could add a method for it, and implement it for both platforms.

Alternatively, just catch PosixError in platform-generic code. I'd rather have stupid implementations than stupid interfaces.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather have stupid implementations than stupid interfaces.

OK yeah that's a very fair point :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK the field is now just on PosixError, and the catch blocks that not throw certain errors are catch PosixError rather than catch SysError.

src/libutil/error.hh Outdated Show resolved Hide resolved
@Ericson2314 Ericson2314 force-pushed the sys-error-split branch 2 times, most recently from 30d33a6 to 1a9778f Compare January 11, 2024 15:59
@Ericson2314 Ericson2314 changed the title SysError, PosixError, WinError, NativeError Separate PosixError from SysError Jan 11, 2024
@Ericson2314 Ericson2314 force-pushed the sys-error-split branch 3 times, most recently from 0da2e75 to 2b4d5ab Compare January 12, 2024 04:42
@edolstra
Copy link
Member

edolstra commented Jan 12, 2024

This is way too much code churn (especially if it's a refactoring for a platform we may never end up supporting). It seems better to me to keep SysError as the exception representing a POSIX error, and introduce other exception types as needed.

@Ericson2314 Ericson2314 changed the title Separate PosixError from SysError Separate SystemError from SysError Jan 12, 2024
@Ericson2314
Copy link
Member Author

Ericson2314 commented Jan 12, 2024

Did the rename @edolstra requested above and in the meeting. SysError is now the POSIX one, and SystemError is the new one above it.

src/libutil/error.hh Outdated Show resolved Hide resolved
src/libutil/namespaces.cc Outdated Show resolved Hide resolved
Most of this is a `catch SysError` -> `catch SystemError` sed. This
is a rather pure-churn change I would like to get out of the way. **The
intersting part is `src/libutil/error.hh`.**

On Unix, we will only throw the `SysError` concrete class, which has
the same constructors that `SystemError` used to have.

On Windows, we will throw `WinError` *and* `SysError`. `WinError`
(which will be created in a later PR), will use a `DWORD` instead of
`int` error value, and `GetLastError()`, which is the Windows equivalent
of the `errno` machinery. Windows will *also* use `SysError` because
Window's "libc" (MSVCRT) implements the POSIX interface, and we use it
too.

As the docs describe, while we *throw* one of the 3 choices above (2
concrete classes or the alias), we should always *catch* `SystemError`.
This ensures no matter how the implementation changes for Windows (e.g.
between `SysError` and `WinError`) the catching logic stays the same
and stays correct.

Co-Authored-By volth <volth@volth.com>
Co-Authored-By Eugene Butler <eugene@eugene4.com>
@Ericson2314 Ericson2314 merged commit c58da62 into NixOS:master Jan 12, 2024
7 checks passed
@Ericson2314 Ericson2314 deleted the sys-error-split branch January 12, 2024 17:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new-cli Relating to the "nix" command repl The Read Eval Print Loop, "nix repl" command and debugger store Issues and pull requests concerning the Nix store windows
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

5 participants