diff --git a/spec/workspace-view-spec.coffee b/spec/workspace-view-spec.coffee index 56c8dc376..09de0bb26 100644 --- a/spec/workspace-view-spec.coffee +++ b/spec/workspace-view-spec.coffee @@ -3,6 +3,7 @@ Q = require 'q' path = require 'path' temp = require 'temp' TextEditorView = require '../src/text-editor-view' +Pane = require '../src/pane' PaneView = require '../src/pane-view' Workspace = require '../src/workspace' @@ -294,3 +295,39 @@ describe "WorkspaceView", -> modalContainer = workspaceElement.querySelector('atom-panel-container.modal') expect(modalContainer.parentNode).toBe workspaceElement + + describe "::saveActivePaneItem()", -> + describe "when there is an error", -> + it "emits a warning notification when the file cannot be saved", -> + spyOn(Pane::, 'saveActiveItem').andCallFake -> + throw new Error("'/some/file' is a directory") + + atom.notifications.onDidAddNotification addedSpy = jasmine.createSpy() + atom.workspace.saveActivePaneItem() + expect(addedSpy).toHaveBeenCalled() + expect(addedSpy.mostRecentCall.args[0].getType()).toBe 'warning' + + it "emits a warning notification when the directory cannot be written to", -> + spyOn(Pane::, 'saveActiveItem').andCallFake -> + throw new Error("ENOTDIR, not a directory '/Some/dir/and-a-file.js'") + + atom.notifications.onDidAddNotification addedSpy = jasmine.createSpy() + atom.workspace.saveActivePaneItem() + expect(addedSpy).toHaveBeenCalled() + expect(addedSpy.mostRecentCall.args[0].getType()).toBe 'warning' + + it "emits a warning notification when the user does not have permission", -> + spyOn(Pane::, 'saveActiveItem').andCallFake -> + throw new Error("EACCES, permission denied '/Some/dir/and-a-file.js'") + + atom.notifications.onDidAddNotification addedSpy = jasmine.createSpy() + atom.workspace.saveActivePaneItem() + expect(addedSpy).toHaveBeenCalled() + expect(addedSpy.mostRecentCall.args[0].getType()).toBe 'warning' + + it "emits a warning notification when the file cannot be saved", -> + spyOn(Pane::, 'saveActiveItem').andCallFake -> + throw new Error("no one knows") + + save = -> atom.workspace.saveActivePaneItem() + expect(save).toThrow() diff --git a/src/workspace.coffee b/src/workspace.coffee index 7b70fa110..98630f7c2 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -555,7 +555,7 @@ class Workspace extends Model # {::saveActivePaneItemAs} # will be called instead. This method does nothing # if the active item does not implement a `.save` method. saveActivePaneItem: -> - @getActivePane().saveActiveItem() + @saveActivePaneItemAndReportErrors('saveActiveItem') # Prompt the user for a path and save the active pane item to it. # @@ -563,7 +563,21 @@ class Workspace extends Model # `.saveAs` on the item with the selected path. This method does nothing if # the active item does not implement a `.saveAs` method. saveActivePaneItemAs: -> - @getActivePane().saveActiveItemAs() + @saveActivePaneItemAndReportErrors('saveActiveItemAs') + + saveActivePaneItemAndReportErrors: (method) -> + try + @getActivePane()[method]() + catch error + if error.message.endsWith('is a directory') + atom.notifications.addWarning("Unable to save file: #{error.message}") + else if error.message.startsWith('EACCES,') + atom.notifications.addWarning("Unable to save file: #{error.message.replace('EACCES, ', '')}") + else if errorMatch = /ENOTDIR, not a directory '([^']+)'/.exec(error.message) + fileName = errorMatch[1] + atom.notifications.addWarning("Unable to save file: A directory in the path '#{fileName}' could not be written to") + else + throw error # Destroy (close) the active pane item. #