         }
     }
     
+}
+
+
+
+// MARK: - Protocol
+
+extension Document: Editable {
+    
+    var textView: NSTextView? {
+        
+        return self.viewController?.focusedTextView
+    }
+    
+}
+
+
+
+// MARK: - Error Handling Extension
+
+fileprivate extension NSDocument {
+    
+    typealias RecoveryHandler = ((Bool) -> Void)
+    
+    
+    /// present an error alert as document modal sheet
+    func presentErrorAsSheet(_ error: Error, recoveryHandler: RecoveryHandler? = nil) {
+        
+        guard let window = self.windowForSheet else {
+            let didRecover = self.presentError(error)
+            recoveryHandler?(didRecover)
+            return
+        }
+        
+        // close previous sheet if exists
+        window.attachedSheet?.orderOut(self)
+        
+        if let recoveryHandler = recoveryHandler {
+            let block = UnsafeMutablePointer<RecoveryHandler>.allocate(capacity: 1)
+            block.pointee = recoveryHandler
+            
+            self.presentError(error, modalFor: window,
+                              delegate: self,
+                              didPresent: #selector(didPresentErrorWithRecovery(didRecover:contextInfo:)),
+                              contextInfo: UnsafeMutableRawPointer(mutating: block))
+            
+        } else {
+            self.presentError(error, modalFor: window,
+                              delegate: nil, didPresent: nil, contextInfo: nil)
+        }
+    }
+    
     
     /// perform didRecoverBlock after recovering presented error
-    private var recoverBlock: ((Bool) -> Void)? = nil
-    func didPresentErrorWithRecovery(didRecover: Bool, block: UnsafeMutableRawPointer) {
-        
-        self.recoverBlock?(didRecover)
-        self.recoverBlock = nil
-    }
-    
-}
-
-
-
-// MARK: - Protocol
-
-extension Document: Editable {
-    
-    var textView: NSTextView? {
-        
-        return self.viewController?.focusedTextView
-    }
+    @objc private func didPresentErrorWithRecovery(didRecover: Bool, contextInfo: UnsafeMutableRawPointer?) {
+        
+        if let recoveryHandler = contextInfo?.assumingMemoryBound(to: RecoveryHandler.self).pointee {
+            recoveryHandler(didRecover)
+        }
+    }
+    
 }
 
 

            try self.checkSavingSafetyForConverting(content: content, encoding: encoding)
            
        } catch let error {
            self.recoverBlock = completionHandler
            self.presentError(error,
                              modalFor: self.windowForSheet!,
                              delegate: self,
                              didPresent: #selector(didPresentErrorWithRecovery(didRecover:block:)),
                              contextInfo: nil)
            return
        }
        

            
        } catch let error {
            NSBeep()
            self.presentErrorAsSheet(error)
        }
    }
    
