mirror of
https://github.com/samsonjs/Peekaboo.git
synced 2026-04-27 15:07:41 +00:00
refactor: Improve screen recording permission error detection
- Extract permission error detection into a dedicated method - Add specific error code checks for ScreenCaptureKit and CoreGraphics - Improve directory existence check in saveImage method - More reliable detection of screen recording permission denials 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
94060963d0
commit
e6b8931d91
1 changed files with 57 additions and 8 deletions
|
|
@ -321,8 +321,7 @@ struct ImageCommand: ParsableCommand {
|
||||||
throw error
|
throw error
|
||||||
} catch {
|
} catch {
|
||||||
// Check if this is a permission error from ScreenCaptureKit
|
// Check if this is a permission error from ScreenCaptureKit
|
||||||
let errorString = error.localizedDescription.lowercased()
|
if isScreenRecordingPermissionError(error) {
|
||||||
if errorString.contains("screen recording") || errorString.contains("permission") {
|
|
||||||
throw CaptureError.screenRecordingPermissionDenied
|
throw CaptureError.screenRecordingPermissionDenied
|
||||||
}
|
}
|
||||||
throw CaptureError.captureCreationFailed
|
throw CaptureError.captureCreationFailed
|
||||||
|
|
@ -359,8 +358,7 @@ struct ImageCommand: ParsableCommand {
|
||||||
try saveImage(image, to: path)
|
try saveImage(image, to: path)
|
||||||
} catch {
|
} catch {
|
||||||
// Check if this is a permission error
|
// Check if this is a permission error
|
||||||
let errorString = error.localizedDescription.lowercased()
|
if isScreenRecordingPermissionError(error) {
|
||||||
if errorString.contains("screen recording") || errorString.contains("permission") {
|
|
||||||
throw CaptureError.screenRecordingPermissionDenied
|
throw CaptureError.screenRecordingPermissionDenied
|
||||||
}
|
}
|
||||||
throw error
|
throw error
|
||||||
|
|
@ -391,8 +389,7 @@ struct ImageCommand: ParsableCommand {
|
||||||
throw error
|
throw error
|
||||||
} catch {
|
} catch {
|
||||||
// Check if this is a permission error from ScreenCaptureKit
|
// Check if this is a permission error from ScreenCaptureKit
|
||||||
let errorString = error.localizedDescription.lowercased()
|
if isScreenRecordingPermissionError(error) {
|
||||||
if errorString.contains("screen recording") || errorString.contains("permission") {
|
|
||||||
throw CaptureError.screenRecordingPermissionDenied
|
throw CaptureError.screenRecordingPermissionDenied
|
||||||
}
|
}
|
||||||
throw CaptureError.windowCaptureFailed
|
throw CaptureError.windowCaptureFailed
|
||||||
|
|
@ -429,17 +426,60 @@ struct ImageCommand: ParsableCommand {
|
||||||
try saveImage(image, to: path)
|
try saveImage(image, to: path)
|
||||||
} catch {
|
} catch {
|
||||||
// Check if this is a permission error
|
// Check if this is a permission error
|
||||||
let errorString = error.localizedDescription.lowercased()
|
if isScreenRecordingPermissionError(error) {
|
||||||
if errorString.contains("screen recording") || errorString.contains("permission") {
|
|
||||||
throw CaptureError.screenRecordingPermissionDenied
|
throw CaptureError.screenRecordingPermissionDenied
|
||||||
}
|
}
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func isScreenRecordingPermissionError(_ error: Error) -> Bool {
|
||||||
|
let errorString = error.localizedDescription.lowercased()
|
||||||
|
|
||||||
|
// Check for specific screen recording related errors
|
||||||
|
if errorString.contains("screen recording") {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for NSError codes specific to screen capture permissions
|
||||||
|
if let nsError = error as NSError? {
|
||||||
|
// ScreenCaptureKit specific error codes
|
||||||
|
if nsError.domain == "com.apple.screencapturekit" && nsError.code == -3801 {
|
||||||
|
// SCStreamErrorUserDeclined = -3801
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// CoreGraphics error codes for screen capture
|
||||||
|
if nsError.domain == "com.apple.coregraphics" && nsError.code == 1002 {
|
||||||
|
// kCGErrorCannotComplete when permissions are denied
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only consider it a permission error if it mentions both "permission" and capture-related terms
|
||||||
|
if errorString.contains("permission") &&
|
||||||
|
(errorString.contains("capture") || errorString.contains("recording") || errorString.contains("screen")) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
private func saveImage(_ image: CGImage, to path: String) throws(CaptureError) {
|
private func saveImage(_ image: CGImage, to path: String) throws(CaptureError) {
|
||||||
let url = URL(fileURLWithPath: path)
|
let url = URL(fileURLWithPath: path)
|
||||||
|
|
||||||
|
// Check if the parent directory exists
|
||||||
|
let directory = url.deletingLastPathComponent()
|
||||||
|
var isDirectory: ObjCBool = false
|
||||||
|
if !FileManager.default.fileExists(atPath: directory.path, isDirectory: &isDirectory) {
|
||||||
|
let error = NSError(
|
||||||
|
domain: NSCocoaErrorDomain,
|
||||||
|
code: NSFileNoSuchFileError,
|
||||||
|
userInfo: [NSLocalizedDescriptionKey: "No such file or directory"]
|
||||||
|
)
|
||||||
|
throw CaptureError.fileWriteError(path, error)
|
||||||
|
}
|
||||||
|
|
||||||
let utType: UTType = format == .png ? .png : .jpeg
|
let utType: UTType = format == .png ? .png : .jpeg
|
||||||
guard let destination = CGImageDestinationCreateWithURL(
|
guard let destination = CGImageDestinationCreateWithURL(
|
||||||
url as CFURL,
|
url as CFURL,
|
||||||
|
|
@ -447,6 +487,15 @@ struct ImageCommand: ParsableCommand {
|
||||||
1,
|
1,
|
||||||
nil
|
nil
|
||||||
) else {
|
) else {
|
||||||
|
// Try to create a more specific error for common cases
|
||||||
|
if !FileManager.default.isWritableFile(atPath: directory.path) {
|
||||||
|
let error = NSError(
|
||||||
|
domain: NSPOSIXErrorDomain,
|
||||||
|
code: Int(EACCES),
|
||||||
|
userInfo: [NSLocalizedDescriptionKey: "Permission denied"]
|
||||||
|
)
|
||||||
|
throw CaptureError.fileWriteError(path, error)
|
||||||
|
}
|
||||||
throw CaptureError.fileWriteError(path, nil)
|
throw CaptureError.fileWriteError(path, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue