Skip to content

Commit b9c35a0

Browse files
committed
fix #15,
rollback by recorder.undo() should not be an UndoState
1 parent 9ea0108 commit b9c35a0

File tree

2 files changed

+33
-3
lines changed

2 files changed

+33
-3
lines changed

__tests__/undo-manager.test.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ test("can time travel with Mutable object", () => {
154154
setUndoManagerDifferentTree(self)
155155
return {
156156
setProp(k: string, v: any) {
157-
;(self.mutable as any).set(k, v)
157+
; (self.mutable as any).set(k, v)
158158
}
159159
}
160160
})
@@ -568,3 +568,31 @@ describe("includeHooks flag", () => {
568568
])
569569
})
570570
})
571+
572+
test("#15 - rollback by recorder.undo() should not be an UndoState", () => {
573+
let _undoManager: any
574+
const Model = types
575+
.model('Model', {
576+
value: 1,
577+
})
578+
.actions(self => {
579+
_undoManager = UndoManager.create({}, { targetStore: self })
580+
function setValue(value: number) {
581+
self.value = value;
582+
throw 'some error throw by actions'
583+
}
584+
return {
585+
setValue,
586+
}
587+
})
588+
589+
const model = Model.create({})
590+
try {
591+
model.setValue(2)
592+
} catch (e) {
593+
expect(e).toBe('some error throw by actions')
594+
}
595+
// rollback successfully and no UndoState
596+
expect(model.value).toBe(1)
597+
expect(_undoManager.history).toHaveLength(0)
598+
})

src/undo-manager.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,10 @@ const UndoManager = types
8585
},
8686
onFinish(call, error) {
8787
const recorder = call.env!.recorder
88-
call.env = undefined
8988
recorder.stop()
90-
9189
if (error === undefined) {
90+
// if no errors from the action, we can safely clean up call.env before proceeding further
91+
call.env = undefined
9292
if (groupRecorders.length > 0) {
9393
const groupRecorder = groupRecorders[groupRecorders.length - 1]
9494
groupRecorder.patches = groupRecorder.patches.concat(recorder.patches)
@@ -99,7 +99,9 @@ const UndoManager = types
9999
;(self as any).addUndoState(recorder)
100100
}
101101
} else {
102+
// if there was an error, we need call.env to filtered action from `recorder.undo -> applyPatch`, so we clean up call.env afterwards
102103
recorder.undo()
104+
call.env = undefined
103105
}
104106
}
105107
})

0 commit comments

Comments
 (0)