Skip to content

Better "file not found" error message#10152

Closed
thePianoKid wants to merge 1 commit into
swiftlang:release/6.4.xfrom
thePianoKid:thePianoKid/fix-file-not-found-error
Closed

Better "file not found" error message#10152
thePianoKid wants to merge 1 commit into
swiftlang:release/6.4.xfrom
thePianoKid:thePianoKid/fix-file-not-found-error

Conversation

@thePianoKid

Copy link
Copy Markdown
Contributor

If you reference a file that doesn't exist in Package.swift, you get this error:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSNull length]: unrecognized selector sent to instance 0x1fc8bf700'
*** First throw call stack:
(
        0   CoreFoundation                      0x000000018f54abf0 __exceptionPreprocess + 176
        1   libobjc.A.dylib                     0x000000018efd691c objc_exception_throw + 88
        2   CoreFoundation                      0x000000018f60bc6c -[NSObject(NSObject) __retain_OA] + 0
        3   CoreFoundation                      0x000000018f4bbbc8 ___forwarding___ + 1480
        4   CoreFoundation                      0x000000018f4bb540 _CF_forwarding_prep_0 + 96
        5   Foundation                          0x00000001910f00a0 $ss5ErrorP10FoundationE20localizedDescriptionSSvg + 980
        6   swift-package                       0x000000010642cb8c $s9WorkspaceAAC22BinaryArtifactsManagerV7extract_18artifactsDirectory18observabilityScopeSayAB15ManagedArtifactVGAJ_6Basics12AbsolutePathVAK013ObservabilityI0CtYaKFAJScgyAISgs5Error_pGzYaKXEfU_AP  7   swift-package                       0x000000010643ed6d $s9WorkspaceAAC22BinaryArtifactsManagerV7extract_18artifactsDirectory18observabilityScopeSayAB15ManagedArtifactVGAJ_6Basics12AbsolutePathVAK013ObservabilityI0CtYaKFAJScgyAISgs5Error_pGzYaKXEfU_AP 8   libswift_Concurrency.dylib          0x0000000293b2aec5 _ZL23completeTaskWithClosurePN5swift12AsyncContextEPNS_10SwiftErrorE + 1
)
libc++abi: terminating due to uncaught exception of type NSException

💣 Program crashed: Signal 6: Backtracing from 0x18f3e45e8...

This PR throws this error instead:

error: local archive of binary target 'bin.zip' at '~/Desktop/Code/sandbox/ReproRdar177455391/bin.zip' does not exist.

@bkhouri

bkhouri commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Since we didn't start the testing against this change, can we target the PR to release/6.4.x and then let the automerger bring it to main?

@thePianoKid thePianoKid changed the base branch from main to release/6.4.x June 1, 2026 15:42
@thePianoKid thePianoKid force-pushed the thePianoKid/fix-file-not-found-error branch from 5e405b5 to dcfd27c Compare June 1, 2026 16:24
Comment on lines +185 to +187
static func localArchiveNotFound(archivePath: AbsolutePath, targetName: String) -> Self {
.init(description: "local archive of binary target '\(targetName)' at '\(archivePath)' does not exist.")
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

suggestion: consider changing targetName to target to ensure the caller sends an "expected" value.

Suggested change
static func localArchiveNotFound(archivePath: AbsolutePath, targetName: String) -> Self {
.init(description: "local archive of binary target '\(targetName)' at '\(archivePath)' does not exist.")
}
static func localArchiveNotFound(archivePath: AbsolutePath, target: Target) -> Self {
.init(description: "local archive of binary target '\(target.name)' at '\(archivePath)' does not exist.")
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think we should refactor every error so it references a target object instead of a string. This is outside the scope of this PR, so I made this one.

@thePianoKid

Copy link
Copy Markdown
Contributor Author

@swift-ci test

@bkhouri

bkhouri commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

@swift-ci test

2 similar comments
@bripeticca

Copy link
Copy Markdown
Contributor

@swift-ci test

@thePianoKid

Copy link
Copy Markdown
Contributor Author

@swift-ci test

@bkhouri

bkhouri commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

@swift-ci test self hosted windows

@bkhouri

bkhouri commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

@swift-ci test macOS

@bkhouri

bkhouri commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

@swift-ci test linux

1 similar comment
@thePianoKid

Copy link
Copy Markdown
Contributor Author

@swift-ci test linux

@thePianoKid

Copy link
Copy Markdown
Contributor Author

@swift-ci test macOS

@thePianoKid

Copy link
Copy Markdown
Contributor Author

hmmm... I found a simpler solution.

I changed the definition of FileSystemError in TSC to fall back to self:

extension FileSystemError: CustomNSError {
    public var errorUserInfo: [String : Any] {
        return [NSLocalizedDescriptionKey: localizedMessage ?? "\(self)"]
    }
}

When the target doesn't exist, an error is thrown with no localizedMessage. Trying to unwrap nil was what was crashing SPM. FileSystemError already has handling for when there is no localizedMessage . It's in Diagnostics.swift.

swiftlang/swift-tools-support-core#563 adds the ?? \(self) to TSC.

I'm closing this PR because swiftlang/swift-tools-support-core#563 already fixes this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants