mirror of
https://github.com/atom/atom.git
synced 2026-01-23 22:08:08 -05:00
Handle exceptions thrown during do/undo/redo
This commit is contained in:
@@ -98,3 +98,57 @@ describe "UndoManager", ->
|
||||
undoManager.undo()
|
||||
expect(buffer.lineForRow(0)).not.toContain("foo")
|
||||
|
||||
it "records transactions that occur prior to an exception", ->
|
||||
spyOn(console, 'error')
|
||||
buffer.setText("jumpstreet")
|
||||
undoManager.transact ->
|
||||
buffer.insert([0,0], "3")
|
||||
buffer.insert([0,0], "2")
|
||||
throw new Error("problem")
|
||||
buffer.insert([0,0], "2")
|
||||
|
||||
expect(console.error).toHaveBeenCalled()
|
||||
expect(buffer.lineForRow(0)).toBe "23jumpstreet"
|
||||
undoManager.undo()
|
||||
expect(buffer.lineForRow(0)).toBe "jumpstreet"
|
||||
|
||||
describe "when a `do` operation throws an exception", ->
|
||||
it "clears the stack", ->
|
||||
spyOn(console, 'error')
|
||||
buffer.setText("word")
|
||||
class FailingOperation
|
||||
do: -> throw new Error("I'm a bad do operation")
|
||||
|
||||
buffer.insert([0,0], "1")
|
||||
undoManager.pushOperation(new FailingOperation())
|
||||
expect(console.error).toHaveBeenCalled()
|
||||
undoManager.undo()
|
||||
expect(buffer.lineForRow(0)).toBe "1word"
|
||||
|
||||
|
||||
describe "when an `undo` operation throws an exception", ->
|
||||
it "clears the stack", ->
|
||||
spyOn(console, 'error')
|
||||
buffer.setText("word")
|
||||
class FailingOperation
|
||||
undo: -> throw new Error("I'm a bad undo operation")
|
||||
|
||||
buffer.insert([0,0], "1")
|
||||
undoManager.pushOperation(new FailingOperation())
|
||||
undoManager.undo()
|
||||
expect(console.error).toHaveBeenCalled()
|
||||
expect(buffer.lineForRow(0)).toBe "1word"
|
||||
|
||||
describe "when an `redo` operation throws an exception", ->
|
||||
it "clears the stack", ->
|
||||
spyOn(console, 'error')
|
||||
buffer.setText("word")
|
||||
class FailingOperation
|
||||
redo: -> throw new Error("I'm a bad undo operation")
|
||||
|
||||
buffer.insert([0,0], "1")
|
||||
undoManager.pushOperation(new FailingOperation())
|
||||
undoManager.undo()
|
||||
undoManager.redo()
|
||||
expect(console.error).toHaveBeenCalled()
|
||||
expect(buffer.lineForRow(0)).toBe "1word"
|
||||
@@ -8,7 +8,10 @@ class UndoManager
|
||||
currentTransaction: null
|
||||
|
||||
constructor: ->
|
||||
@startBatchCallCount = 0
|
||||
@clear()
|
||||
|
||||
clear: ->
|
||||
@currentTransaction = null
|
||||
@undoHistory = []
|
||||
@redoHistory = []
|
||||
|
||||
@@ -18,29 +21,50 @@ class UndoManager
|
||||
else
|
||||
@undoHistory.push([operation])
|
||||
@redoHistory = []
|
||||
operation.do?(editSession)
|
||||
|
||||
try
|
||||
operation.do?(editSession)
|
||||
catch e
|
||||
console.error e.stack
|
||||
@clear()
|
||||
|
||||
transact: (fn) ->
|
||||
safeFn = ->
|
||||
try
|
||||
fn()
|
||||
catch e
|
||||
console.error e.stack
|
||||
|
||||
if @currentTransaction
|
||||
fn()
|
||||
safeFn()
|
||||
else
|
||||
@currentTransaction = []
|
||||
fn()
|
||||
@undoHistory.push(@currentTransaction) if @currentTransaction.length
|
||||
safeFn()
|
||||
@undoHistory.push(@currentTransaction) if @currentTransaction?.length
|
||||
@currentTransaction = null
|
||||
|
||||
undo: (editSession) ->
|
||||
if batch = @undoHistory.pop()
|
||||
opsInReverse = new Array(batch...)
|
||||
opsInReverse.reverse()
|
||||
op.undo?(editSession) for op in opsInReverse
|
||||
@redoHistory.push batch
|
||||
batch.oldSelectionRanges
|
||||
try
|
||||
if batch = @undoHistory.pop()
|
||||
opsInReverse = new Array(batch...)
|
||||
opsInReverse.reverse()
|
||||
op.undo?(editSession) for op in opsInReverse
|
||||
|
||||
@redoHistory.push batch
|
||||
batch.oldSelectionRanges
|
||||
catch e
|
||||
console.error e.stack
|
||||
@clear()
|
||||
|
||||
redo: (editSession) ->
|
||||
if batch = @redoHistory.pop()
|
||||
for op in batch
|
||||
op.do?(editSession)
|
||||
op.redo?(editSession)
|
||||
@undoHistory.push(batch)
|
||||
batch.newSelectionRanges
|
||||
try
|
||||
if batch = @redoHistory.pop()
|
||||
for op in batch
|
||||
op.do?(editSession)
|
||||
op.redo?(editSession)
|
||||
|
||||
@undoHistory.push(batch)
|
||||
batch.newSelectionRanges
|
||||
catch e
|
||||
console.error e.stack
|
||||
@clear()
|
||||
|
||||
Reference in New Issue
Block a user