FileManager.copyItem not throwing?

I have code as follows:

let fileManager = FileManager.default
do {
     try fileManager.createDirectory(at: destination.deletingLastPathComponent(), withIntermediateDirectories: true, attributes: nil)
     try fileManager.copyItem(at: source, to: destination)
     handler(true, nil)
}
catch let theError as NSError {
     if theError.code == NSFileWriteNoPermissionError {
         ...
     }
     else {
         ...
     }
}
catch {
      handler(false, NSError(...))
}

Running on macOS 10.12.6, Xcode 8.3.2, I get to the copyItem call, which shows an error on the console:

2017-11-11 11:18:25.931446+1000 MyApp[32662:2408351] open on /path/to/file: Permission denied

But it doesn't go to either of my catch blocks, but goes to the following line, where the completion handler is to be run. What is going on?

John

···

--
John Brownie
SIL-PNG, Ukarumpa, Eastern Highlands, Papua New Guinea
Mussau-Emira language, New Ireland Province, Papua New Guinea

Running on macOS 10.12.6, Xcode 8.3.2, I get to the copyItem call, which shows an error on the console:

2017-11-11 11:18:25.931446+1000 MyApp[32662:2408351] open on /path/to/file: Permission denied

But it doesn't go to either of my catch blocks, but goes to the following line, where the completion handler is to be run. What is going on?

Known (by Apple) bug. My report was closed as a duplicate of 30350792.

My workaround is to do this in my do block after attempting to copy a file to saveFileUrl:

    try fileManager.copyItem(at: url, to: saveFileUrl)
    /// DANGER WILL ROBINSON -- the above call can fail to return an
    /// error when the file is not copied. radar filed and
    /// closed as a DUPLICATE OF 30350792 which is still open.
    /// As a result I must verify that the copied file exists
    if !fileManager.fileExists(atPath: (saveFileUrl.path)) {
        unexpected(error: nil,
                   "Cannot copy \(url.path) to \(saveFileUrl.path)")
        return false
    }

which duplicates what the catch block would do.

Marc

I don’t have any inside knowledge on this, i.e. I am not certain I am correct, but my understanding was that you were meant to let it throw and catch the error rather than test before hand.

-- Howard.

···

On 11 Nov 2017, at 12:51 pm, Marco S Hyman via swift-users <swift-users@swift.org> wrote:

Running on macOS 10.12.6, Xcode 8.3.2, I get to the copyItem call, which shows an error on the console:

2017-11-11 11:18:25.931446+1000 MyApp[32662:2408351] open on /path/to/file: Permission denied

But it doesn't go to either of my catch blocks, but goes to the following line, where the completion handler is to be run. What is going on?

Known (by Apple) bug. My report was closed as a duplicate of 30350792.

My workaround is to do this in my do block after attempting to copy a file to saveFileUrl:

   try fileManager.copyItem(at: url, to: saveFileUrl)
   /// DANGER WILL ROBINSON -- the above call can fail to return an
   /// error when the file is not copied. radar filed and
   /// closed as a DUPLICATE OF 30350792 which is still open.
   /// As a result I must verify that the copied file exists
   if !fileManager.fileExists(atPath: (saveFileUrl.path)) {
       unexpected(error: nil,
                  "Cannot copy \(url.path) to \(saveFileUrl.path)")
       return false
   }

which duplicates what the catch block would do.

Marc
_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

Are you still seeing this on 10.13?

Share and Enjoy

···

On 11 Nov 2017, at 01:51, Marco S Hyman via swift-users <swift-users@swift.org> wrote:

My report was closed as a duplicate of 30350792.

--
Quinn "The Eskimo!" <http://www.apple.com/developer/>
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

Also...

My workaround for this bug assumes you tested for the destination file presence BEFORE doing the copy and removing/moving one away if found. Otherwise you won’t know if you are looking at an older version of the file when testing after the copy.

In my code I’m making a versioned backup and loop over file names (file-1, file-2, ... file-n) until I find a name that is not in use and then attempt the copy.

Marc

···

On Nov 11, 2017, at 2:07 PM, John Brownie <john_brownie@sil.org> wrote:

And that's the point. The throw does not happen. An error is logged, but execution continues as though there was no error.

And that's the point. The throw does not happen. An error is logged, but execution continues as though there was no error.

John

···

Howard Lovatt <mailto:howard.lovatt@gmail.com>
12 November 2017 at 07:43
I don’t have any inside knowledge on this, i.e. I am not certain I am correct, but my understanding was that you were meant to let it throw and catch the error rather than test before hand.

-- Howard.

Marco S Hyman <mailto:marc@snafu.org>
11 November 2017 at 11:51

Known (by Apple) bug. My report was closed as a duplicate of 30350792.

My workaround is to do this in my do block after attempting to copy a file to saveFileUrl:

try fileManager.copyItem(at: url, to: saveFileUrl)
/// DANGER WILL ROBINSON -- the above call can fail to return an
/// error when the file is not copied. radar filed and
/// closed as a DUPLICATE OF 30350792 which is still open.
/// As a result I must verify that the copied file exists
if !fileManager.fileExists(atPath: (saveFileUrl.path)) {
unexpected(error: nil,
"Cannot copy \(url.path) to \(saveFileUrl.path)")
return false
}

which duplicates what the catch block would do.

Marc
John Brownie <mailto:john_brownie@sil.org>
11 November 2017 at 11:31
I have code as follows:

let fileManager = FileManager.default
do {
    try fileManager.createDirectory(at: destination.deletingLastPathComponent(), withIntermediateDirectories: true, attributes: nil)
    try fileManager.copyItem(at: source, to: destination)
    handler(true, nil)
}
catch let theError as NSError {
    if theError.code == NSFileWriteNoPermissionError {
        ...
    }
    else {
        ...
    }
}
catch {
     handler(false, NSError(...))
}

Running on macOS 10.12.6, Xcode 8.3.2, I get to the copyItem call, which shows an error on the console:

2017-11-11 11:18:25.931446+1000 MyApp[32662:2408351] open on /path/to/file: Permission denied

But it doesn't go to either of my catch blocks, but goes to the following line, where the completion handler is to be run. What is going on?

John

--
John Brownie
SIL-PNG, Ukarumpa, Eastern Highlands, Papua New Guinea
Mussau-Emira language, New Ireland Province, Papua New Guinea

I don’t know, let me test...

Very good... the copy fails into the catch block as it should using Xcode 9.1 on macOS 10.13. I’m going to keep my workaround in my code for a while, anyway :slight_smile:

Marc

···

On 11 Nov 2017, at 01:51, Marco S Hyman via swift-users <swift-users@swift.org> wrote:

My report was closed as a duplicate of 30350792.

Are you still seeing this on 10.13?