From 9589c2d5029835e20117c270ccd1ded80f6ad5e9 Mon Sep 17 00:00:00 2001 From: Aditya Singh Date: Fri, 29 May 2026 00:43:58 -0700 Subject: [PATCH] Replace precondition with fatalError for missing permissions on .create FileDescriptor.open traps when options contains .create but permissions is nil. The previous precondition could elide its message in optimized builds, leaving users to hunt through source to diagnose the crash. Use fatalError with a descriptive message so the reason is always present in the crash dump, and document the trapping behavior. Fixes #78 --- Sources/System/FileOperations.swift | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Sources/System/FileOperations.swift b/Sources/System/FileOperations.swift index 9ddc16c3..71ea6e21 100644 --- a/Sources/System/FileOperations.swift +++ b/Sources/System/FileOperations.swift @@ -16,6 +16,8 @@ extension FileDescriptor { /// - mode: The read and write access to use. /// - options: The behavior for opening the file. /// - permissions: The file permissions to use for created files. + /// This value must not be `nil` when `options` contains `.create`; + /// passing `nil` in that case is a programmer error and traps at runtime. /// - retryOnInterrupt: Whether to retry the open operation /// if it throws ``Errno/interrupted``. /// The default is `true`. @@ -55,6 +57,8 @@ extension FileDescriptor { /// - mode: The read and write access to use. /// - options: The behavior for opening the file. /// - permissions: The file permissions to use for created files. + /// This value must not be `nil` when `options` contains `.create`; + /// passing `nil` in that case is a programmer error and traps at runtime. /// - retryOnInterrupt: Whether to retry the open operation /// if it throws ``Errno/interrupted``. /// The default is `true`. @@ -88,8 +92,10 @@ extension FileDescriptor { if let permissions = permissions { return system_open(path, oFlag, permissions.rawValue) } - precondition(!options.contains(.create), - "Create must be given permissions") + if options.contains(.create) { + fatalError( + "FileDescriptor.open: 'permissions' must not be nil when 'options' contains '.create'") + } return system_open(path, oFlag) } return descOrError.map { FileDescriptor(rawValue: $0) } @@ -102,6 +108,8 @@ extension FileDescriptor { /// - mode: The read and write access to use. /// - options: The behavior for opening the file. /// - permissions: The file permissions to use for created files. + /// This value must not be `nil` when `options` contains `.create`; + /// passing `nil` in that case is a programmer error and traps at runtime. /// - retryOnInterrupt: Whether to retry the open operation /// if it throws ``Errno/interrupted``. /// The default is `true`.