From 79778b4a0038da5d880d6bd362e92a22d4c469d9 Mon Sep 17 00:00:00 2001 From: Neil Lindquist Date: Tue, 19 Jun 2018 22:26:42 -0500 Subject: [PATCH 1/6] Display backtrace in debug pane --- lib/atom-slime-debugger-view.coffee | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/lib/atom-slime-debugger-view.coffee b/lib/atom-slime-debugger-view.coffee index d99b0a9..1541d63 100644 --- a/lib/atom-slime-debugger-view.coffee +++ b/lib/atom-slime-debugger-view.coffee @@ -23,6 +23,15 @@ class DebuggerView extends ScrollView @li class:"", => @button class:"inline-block-tight btn", "Option 3" @text "Description of option 3" + @h3 "Stack Trace:" + @ol outlet:"stackTrace", start:"0", => + @li class:"", => + @text "Description of frame 1" + @li class:"", => + @text "Description of frame 2" + @li class:"", => + @text "Description of frame 3" + @button outlet:"fullStackTrace", class:"inline-block-tight btn", "Show All Stack Frames" setup: (@swank, @info) -> @@ -40,12 +49,31 @@ class DebuggerView extends ScrollView this.find('.restart-button').on 'click', (event) => @restart_click_handler event + @render_stack_trace(@info.stack_frames) + + @fullStackTrace.on 'click', (event) => + @load_full_stack_trace event + restart_click_handler: (event) -> restartindex = event.target.getAttribute('restartindex') level = event.target.getAttribute('level') thread = event.target.getAttribute('thread') @swank.debug_invoke_restart(level, restartindex, thread) + load_full_stack_trace: (event) -> + @fullStackTrace.remove() + thread = @info.thread + @swank.debug_get_stack_trace(thread).then (stack_trace) => + @info.stack_frame = stack_trace + @render_stack_trace(stack_trace) + + render_stack_trace: (trace) => + @stackTrace.empty() + for frame, i in trace + @stackTrace.append $$ -> + @li class:"", => + @text frame.description + getTitle: -> "Debugger" getURI: -> "slime://debug" # TODO -- fix From cd4b962d8591f4cd5ce3ea917dfa1db68f48cddd Mon Sep 17 00:00:00 2001 From: Neil Lindquist Date: Sat, 23 Jun 2018 19:38:23 -0500 Subject: [PATCH 2/6] Add support for multiple levels of debugging --- lib/atom-slime-debugger-view.coffee | 7 ++-- lib/atom-slime-repl-view.coffee | 56 +++++++++++++++++------------ 2 files changed, 38 insertions(+), 25 deletions(-) diff --git a/lib/atom-slime-debugger-view.coffee b/lib/atom-slime-debugger-view.coffee index 1541d63..bed7a15 100644 --- a/lib/atom-slime-debugger-view.coffee +++ b/lib/atom-slime-debugger-view.coffee @@ -39,6 +39,8 @@ class DebuggerView extends ScrollView @errorType.html @info.type level = @info.level thread = @info.thread + @active = true + @restarts.empty() for restart, i in @info.restarts @restarts.append $$ -> @@ -58,6 +60,7 @@ class DebuggerView extends ScrollView restartindex = event.target.getAttribute('restartindex') level = event.target.getAttribute('level') thread = event.target.getAttribute('thread') + @active = false @swank.debug_invoke_restart(level, restartindex, thread) load_full_stack_trace: (event) -> @@ -76,6 +79,6 @@ class DebuggerView extends ScrollView getTitle: -> "Debugger" - getURI: -> "slime://debug" # TODO -- fix + getURI: -> "slime://debug/"+@info.level isEqual: (other) -> - other instanceof DebuggerView + other instanceof DebuggerView and other.info.level == @info.level diff --git a/lib/atom-slime-repl-view.coffee b/lib/atom-slime-repl-view.coffee index 3559a91..f202441 100644 --- a/lib/atom-slime-repl-view.coffee +++ b/lib/atom-slime-repl-view.coffee @@ -238,11 +238,9 @@ class REPLView # Debug functions @swank.on 'debug_setup', (obj) => @createDebugTab(obj) @swank.on 'debug_activate', (obj) => - # TODO - keep track of differnet levels - @showDebugTab() + @showDebugTab(obj.level) @swank.on 'debug_return', (obj) => - # TODO - keep track of different levels - @closeDebugTab() + @closeDebugTab(obj.level) # Profile functions @swank.on 'profile_command_complete', (msg) => @@ -315,28 +313,40 @@ class REPLView setupDebugger: () -> + @dbgv = [] process.nextTick => @subs.add atom.workspace.addOpener (filePath) => - if filePath == 'slime://debug' - return @dbgv + if filePath.startsWith('slime://debug/') + level = filePath.slice(14) + return @dbgv[level-1] @subs.add @replPane.onWillDestroyItem (e) => - if e.item == @dbgv - @swank.debug_escape_all() - - + if e.item in @dbgv + level = e.item.info.level #1 based indices + if level < @dbgv.length + #recursively delete lower levels + @closeDebugTab(level+1) + if e.item.active + @swank.debug_abort_current_level(e.item.level, e.item.info.thread) + e.item.active = false createDebugTab: (obj) -> - @dbgv = new DebuggerView - @dbgv.setup(@swank, obj) - - showDebugTab: () -> - @replPane.activate() - atom.workspace.open('slime://debug').then (d) => - # TODO - doesn't work - #elt = atom.views.getView(d) - #atom.commands.add elt, 'q': (event) => @closeDebugTab() - - closeDebugTab: () -> - @replPane.destroyItem(@dbgv) + if obj.level > @dbgv.length + @dbgv.push(new DebuggerView) + debug = @dbgv[obj.level-1] + debug.setup(@swank, obj) + + showDebugTab: (level) -> + # A slight pause is needed before showing for when an error occurs immediatly after resolving another error + setTimeout(() => + @replPane.activate() + atom.workspace.open('slime://debug/'+level).then (d) => + # TODO - doesn't work + #elt = atom.views.getView(d) + #atom.commands.add elt, 'q': (event) => @closeDebugTab(level) + , 10) + + closeDebugTab: (level) -> + @replPane.destroyItem(@dbgv[level-1]) + @dbgv.pop() # Set the package and prompt @@ -347,6 +357,6 @@ class REPLView destroy: -> if @swank.connected - @closeDebugTab() + @closeDebugTab(1) @subs.dispose() @swank.quit() From 5f0c1ed71520f88e29908b00b8361d7eef925e0a Mon Sep 17 00:00:00 2001 From: Neil Lindquist Date: Sat, 23 Jun 2018 15:36:17 -0500 Subject: [PATCH 3/6] Create basic frame inspection Features include * viewing local variables * viewing catch tags * restarting frames * returning specific values from frames * disassembling frames --- README.md | 1 - lib/atom-slime-debugger-view.coffee | 36 ++++++++---- lib/atom-slime-frame-info.coffee | 87 +++++++++++++++++++++++++++++ lib/atom-slime-repl-view.coffee | 11 +++- 4 files changed, 120 insertions(+), 15 deletions(-) create mode 100644 lib/atom-slime-frame-info.coffee diff --git a/README.md b/README.md index fbca0e9..c95813f 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,6 @@ Current features of this package: Future features: - Interactive object inspection -- Stack trace in debugger - "Compile this file" command - "Who calls this function" command diff --git a/lib/atom-slime-debugger-view.coffee b/lib/atom-slime-debugger-view.coffee index bed7a15..3135b57 100644 --- a/lib/atom-slime-debugger-view.coffee +++ b/lib/atom-slime-debugger-view.coffee @@ -1,5 +1,6 @@ {CompositeDisposable} = require 'atom' {$, $$, TextEditorView, View, SelectListView, ScrollView} = require 'atom-space-pen-views' +FrameInfoView = require './atom-slime-frame-info' module.exports = class DebuggerView extends ScrollView @@ -24,16 +25,16 @@ class DebuggerView extends ScrollView @button class:"inline-block-tight btn", "Option 3" @text "Description of option 3" @h3 "Stack Trace:" - @ol outlet:"stackTrace", start:"0", => - @li class:"", => - @text "Description of frame 1" - @li class:"", => - @text "Description of frame 2" - @li class:"", => - @text "Description of frame 3" + @div class:"select-list", => + @ol outlet:"stackTrace", class:'list-group mark-active', start:"0", => + @li class:"", => + @text "Description of frame 1" + @li class:"", => + @text "Description of frame 2" + @li class:"", => + @text "Description of frame 3" @button outlet:"fullStackTrace", class:"inline-block-tight btn", "Show All Stack Frames" - setup: (@swank, @info) -> @errorTitle.html @info.title @errorType.html @info.type @@ -53,9 +54,6 @@ class DebuggerView extends ScrollView @render_stack_trace(@info.stack_frames) - @fullStackTrace.on 'click', (event) => - @load_full_stack_trace event - restart_click_handler: (event) -> restartindex = event.target.getAttribute('restartindex') level = event.target.getAttribute('level') @@ -72,10 +70,24 @@ class DebuggerView extends ScrollView render_stack_trace: (trace) => @stackTrace.empty() + thread = @info.thread for frame, i in trace @stackTrace.append $$ -> @li class:"", => - @text frame.description + @button class:'inline-block-tight frame-info-button btn', frame_index:frame.frame_number, thread:thread, "Frame Info" + @text i + ": " + frame.description + + this.find('.frame-info-button ').on 'click', (event) => + @view_frame_click_handler event + + view_frame_click_handler: (event) -> + frame_index = event.target.getAttribute('frame_index') + thread = thread + if not @frame_info? + @frame_info = new FrameInfoView + @frame_info.setup(@swank, @info, Number(frame_index), @) + + atom.workspace.open('slime://debug/'+@info.level+'/frame') getTitle: -> "Debugger" diff --git a/lib/atom-slime-frame-info.coffee b/lib/atom-slime-frame-info.coffee new file mode 100644 index 0000000..09ee4b2 --- /dev/null +++ b/lib/atom-slime-frame-info.coffee @@ -0,0 +1,87 @@ +{CompositeDisposable} = require 'atom' +{$, $$, View, SelectListView, ScrollView} = require 'atom-space-pen-views' + +module.exports = +class FrameInfoView extends ScrollView + @content: -> + @div outlet:'main', class:'atom-slime-debugger padded', => + @h1 outlet:'frameName', 'Frame Name' + @div class:'select-list', => + @ol outlet:'navigation', class:'list-group mark-active', => + @li 'Navigate to adjacent stack frames' + @h3 'Local Variables' + @div class:'select-list', => + @ol outlet:'locals', class:'list-group mark-active', => + @li 'Description of var 0' + @div outlet: 'catchTagsDiv', class:'select-list', => + @h3 'Catch Tags' + @ol outlet:'catchTags', start:'0', => + @li 'Description of tag 0' + @button outlet:'restartFrame', class:'inline-block-tight btn', 'Restart Frame' + @input outlet:'frameReturnValue', class:'inline-block-tight', type:'text' + @button outlet:'returnFromFrame', class:'inline-block-tight btn', 'Return From Frame' + @button outlet:'disassemble', class:'inline-block-tight btn', 'Disassemble Frame' + @div outlet:'disassembleOutput' + + setup: (@swank, @info, @frame_index, @debugView) -> + frame = @info.stack_frames[@frame_index] + + @frameName.html @frame_index + ': ' + frame.description + + @navigation.empty() + if @frame_index > 0 + @add_navigation_item(0, description = @info.stack_frames[0].description, 'Stack Top') + if @frame_index > 1 + @add_navigation_item(@frame_index-1, description = @info.stack_frames[@frame_index-1].description, 'Up') + if @frame_index < @info.stack_frames.length - 1 + @add_navigation_item(@frame_index+1, description = @info.stack_frames[@frame_index+1].description, 'Down') + + this.find('.frame-navigation-button').on 'click', (event) => + @setup(@swank, @info, Number(event.target.getAttribute('frame_index')), @debugView) + + if frame.restartable + @restartFrame[0].disabled = false + @restartFrame.on 'click', (event) => + @debugView.active = false + @swank.debug_restart_frame(@frame_index, @info.thread) + else + @restartFrame[0].disabled = true + + @returnFromFrame.on 'click', (event) => + @debugView.active = false + @swank.debug_return_from_frame(@frame_index, @frameReturnValue[0].value, @info.thread) + + @disassembleOutput.text = '' + @disassemble.on 'click', (event) => + @swank.debug_disassemble_frame(@frame_index, @info.thread).then (output) => + @disassembleOutput.text = output + + @swank.debug_stack_frame_details(@frame_index, @info.stack_frames, @info.thread).then (frame) => + @locals.empty() + if frame.locals.length > 0 + for local, i in frame.locals + @locals.append $$ -> + @li local.id + ': ' + local.name + ' = ' + local.value + else + @locals.append $$ -> + @li '' + if frame.catch_tags.length > 0 + @catchTagsDiv.show() + @catchTags.empty() + for tag, i in frame.catch_tags + @catchTags.append $$ -> + @li i + ': ' + tag + else + @catchTagsDiv.hide() + + add_navigation_item: (index, frame_description, label) -> + @navigation.append $$ -> + @li class:"", => + @button class:'inline-block-tight frame-navigation-button btn', frame_index:index, label + @text index+": " + frame_description + + + getTitle: -> 'Frame Info' + getURI: => 'slime://debug/' + @info.level + '/frame' + isEqual: (other) => + other instanceof FrameInfoView and @info.level == other.info.level diff --git a/lib/atom-slime-repl-view.coffee b/lib/atom-slime-repl-view.coffee index f202441..ba86d5f 100644 --- a/lib/atom-slime-repl-view.coffee +++ b/lib/atom-slime-repl-view.coffee @@ -238,7 +238,7 @@ class REPLView # Debug functions @swank.on 'debug_setup', (obj) => @createDebugTab(obj) @swank.on 'debug_activate', (obj) => - @showDebugTab(obj.level) + @showDebugTab(obj.level) @swank.on 'debug_return', (obj) => @closeDebugTab(obj.level) @@ -316,9 +316,12 @@ class REPLView @dbgv = [] process.nextTick => @subs.add atom.workspace.addOpener (filePath) => - if filePath.startsWith('slime://debug/') + if filePath.match(///^slime://debug/\d+$///) level = filePath.slice(14) return @dbgv[level-1] + if filePath.match(///^slime://debug/\d+/frame$///) + level = filePath.slice(14, -6) + return @dbgv[level-1].frame_info @subs.add @replPane.onWillDestroyItem (e) => if e.item in @dbgv level = e.item.info.level #1 based indices @@ -328,6 +331,10 @@ class REPLView if e.item.active @swank.debug_abort_current_level(e.item.level, e.item.info.thread) e.item.active = false + if e.item.frame_info? + @replPane.destroyItem(e.item.frame_info) + + createDebugTab: (obj) -> if obj.level > @dbgv.length @dbgv.push(new DebuggerView) From 6793c2a14596787a8c4aaa994da7acdad0d7c7f0 Mon Sep 17 00:00:00 2001 From: Neil Lindquist Date: Mon, 25 Jun 2018 20:14:55 -0500 Subject: [PATCH 4/6] Add support for showing a frame's source --- lib/atom-slime-frame-info.coffee | 63 ++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/lib/atom-slime-frame-info.coffee b/lib/atom-slime-frame-info.coffee index 09ee4b2..d84b042 100644 --- a/lib/atom-slime-frame-info.coffee +++ b/lib/atom-slime-frame-info.coffee @@ -17,6 +17,7 @@ class FrameInfoView extends ScrollView @h3 'Catch Tags' @ol outlet:'catchTags', start:'0', => @li 'Description of tag 0' + @button outlet:'viewSource', class:'inline-block-tightb btn', 'View Frame Source' @button outlet:'restartFrame', class:'inline-block-tight btn', 'Restart Frame' @input outlet:'frameReturnValue', class:'inline-block-tight', type:'text' @button outlet:'returnFromFrame', class:'inline-block-tight btn', 'Return From Frame' @@ -39,6 +40,9 @@ class FrameInfoView extends ScrollView this.find('.frame-navigation-button').on 'click', (event) => @setup(@swank, @info, Number(event.target.getAttribute('frame_index')), @debugView) + @viewSource.on 'click', (event) => + @display_frame_source() + if frame.restartable @restartFrame[0].disabled = false @restartFrame.on 'click', (event) => @@ -80,6 +84,65 @@ class FrameInfoView extends ScrollView @button class:'inline-block-tight frame-navigation-button btn', frame_index:index, label @text index+": " + frame_description + display_frame_source: () => + frame_index = @frame_index + @swank.debug_frame_source(frame_index, @info.thread).then (source_location) -> + if source_location.buffer_type == 'error' + editor_promise = Promise.reject(source_location.error) + else if source_location.buffer_type == 'buffer' or source_location.buffer_type == 'buffer-and-file' + # look through editors for an editor with a matching name + for editor in atom.workspace.getTextEditors() + if editor.getTitle() == source_location.buffer_name + pane = atom.workspace.paneForItem(editor) + pane.activate() + pane.activateItem(editor) + editor_promise = Promise.resolve(editor) + break + if source_location.buffer_type == 'buffer-and-file' + # fall back to file if nessacery + editor_promise ?= atom.workspace.open(source_location.file) + else + editor_promise ?= Promise.reject('No editor named '+source_location.buffer_name) + else if source_location.buffer_type == 'file' + editor_promise = atom.workspace.open(source_location.file) + else if source_location.buffer_type == 'source-form' + editor = atom.workspace.buildTextEditor() + editor.setText(source_location.source_form) + #change default title + editor.getTitle = -> editor.getFileName() ? 'Frame ' + frame_index + ' Source' + #change condition for save prompt for unsaved file + editor_buffer = editor.getBuffer() + editor_buffer.isModified = -> + if editor_buffer.file?.existsSync() + editor_buffer.buffer.isModified() + else + editor_buffer.getText() != source_location.source_form + #add to active pane + activePane = atom.workspace.getActivePane() + activePane.addItem(editor) + activePane.activateItem(editor) + editor_promise = Promise.resolve(editor) + else + # TODO zip + editor_promise = Promise.reject('Unsupported source type given: "'+source_location.buffer_type+'"') + + #need source_location, so use a closure to pass it to the next part + editor_promise.then (editor) -> + if source_location.position_type == 'line' + row = source_location.position_line + col = location.position_column ? 0 + editor.setCursorBufferPosition(new Point(row, col)) + else if source_location.position_type == 'position' + position = editor.getBuffer() + .positionForCharacterIndex(source_location.position_offset) + editor.setCursorBufferPosition(position) + else + #TODO function-name + #TODO source-path + #TODO method + Promise.reject('Unsupported position type given: "'+source_location.position_type+'"') + .catch (error) -> + atom.notifications.addError 'Cannot show frame source: '+error getTitle: -> 'Frame Info' getURI: => 'slime://debug/' + @info.level + '/frame' From 3cc1f7a1b1dd113f552bd8a0e19c196b23c7d57d Mon Sep 17 00:00:00 2001 From: Neil Lindquist Date: Wed, 27 Jun 2018 21:00:12 -0500 Subject: [PATCH 5/6] Add eval in frame option Also, the layout of frame information was rearranged --- lib/atom-slime-debugger-view.coffee | 2 +- lib/atom-slime-frame-info.coffee | 41 ++++++++++++++++++++++------- lib/atom-slime-repl-view.coffee | 2 +- styles/atom-slime.less | 6 +++++ 4 files changed, 39 insertions(+), 12 deletions(-) diff --git a/lib/atom-slime-debugger-view.coffee b/lib/atom-slime-debugger-view.coffee index 3135b57..9acfaa1 100644 --- a/lib/atom-slime-debugger-view.coffee +++ b/lib/atom-slime-debugger-view.coffee @@ -35,7 +35,7 @@ class DebuggerView extends ScrollView @text "Description of frame 3" @button outlet:"fullStackTrace", class:"inline-block-tight btn", "Show All Stack Frames" - setup: (@swank, @info) -> + setup: (@swank, @info, @replView) -> @errorTitle.html @info.title @errorType.html @info.type level = @info.level diff --git a/lib/atom-slime-frame-info.coffee b/lib/atom-slime-frame-info.coffee index d84b042..0f89466 100644 --- a/lib/atom-slime-frame-info.coffee +++ b/lib/atom-slime-frame-info.coffee @@ -17,12 +17,24 @@ class FrameInfoView extends ScrollView @h3 'Catch Tags' @ol outlet:'catchTags', start:'0', => @li 'Description of tag 0' - @button outlet:'viewSource', class:'inline-block-tightb btn', 'View Frame Source' - @button outlet:'restartFrame', class:'inline-block-tight btn', 'Restart Frame' - @input outlet:'frameReturnValue', class:'inline-block-tight', type:'text' - @button outlet:'returnFromFrame', class:'inline-block-tight btn', 'Return From Frame' - @button outlet:'disassemble', class:'inline-block-tight btn', 'Disassemble Frame' - @div outlet:'disassembleOutput' + @div class:'select-list', => + @ol class:'list-group mark-active', => + @li => + @button outlet:'viewSource', class:'inline-block-tight btn', 'View Frame Source' + @li => + @button outlet:'restartFrame', class:'inline-block-tight btn', 'Restart Frame' + @li => + @button outlet:'disassemble', class:'inline-block-tight btn', 'Disassemble Frame' + @div outlet:'disassembleDiv', => + @h3 'Disassembled:' + @span outlet:'disassembleOutput', class:'slime-message', '' + @ol class:'list-group mark-active', => + @li => + @input outlet:'frameReturnValue', class:'native-key-bindings', type:'text', size:50 + @li => + @button outlet:'returnFromFrame', class:'inline-block-tight btn', 'Return From Frame' + @li => + @button outlet:'evalInFrame', class:'inline-block-tight btn', 'Eval in Frame' setup: (@swank, @info, @frame_index, @debugView) -> frame = @info.stack_frames[@frame_index] @@ -51,14 +63,23 @@ class FrameInfoView extends ScrollView else @restartFrame[0].disabled = true + @disassembleDiv.hide() + @disassemble.on 'click', (event) => + @swank.debug_disassemble_frame(@frame_index, @info.thread).then (output) => + @disassembleOutput.text(output) + @disassembleDiv.show() + @returnFromFrame.on 'click', (event) => @debugView.active = false @swank.debug_return_from_frame(@frame_index, @frameReturnValue[0].value, @info.thread) - @disassembleOutput.text = '' - @disassemble.on 'click', (event) => - @swank.debug_disassemble_frame(@frame_index, @info.thread).then (output) => - @disassembleOutput.text = output + @evalInFrame.on 'click', (event) => + input = @frameReturnValue.val() + @frameReturnValue.val('') + @swank.debug_eval_in_frame(@frame_index, input, @info.thread).then (result) => + replView = @debugView.replView + replView.print_string_callback(result+'\n') + replView.replPane.activateItem(replView.editor) @swank.debug_stack_frame_details(@frame_index, @info.stack_frames, @info.thread).then (frame) => @locals.empty() diff --git a/lib/atom-slime-repl-view.coffee b/lib/atom-slime-repl-view.coffee index ba86d5f..3c99743 100644 --- a/lib/atom-slime-repl-view.coffee +++ b/lib/atom-slime-repl-view.coffee @@ -339,7 +339,7 @@ class REPLView if obj.level > @dbgv.length @dbgv.push(new DebuggerView) debug = @dbgv[obj.level-1] - debug.setup(@swank, obj) + debug.setup(@swank, obj, @) showDebugTab: (level) -> # A slight pause is needed before showing for when an error occurs immediatly after resolving another error diff --git a/styles/atom-slime.less b/styles/atom-slime.less index 8e0f15e..138e192 100644 --- a/styles/atom-slime.less +++ b/styles/atom-slime.less @@ -158,3 +158,9 @@ bubble-multiline-message { .slime-object-introspected h4 { border-bottom: solid 1px @base-border-color; } + + +// frame info +.slime-message { + white-space: pre-line; +} From 2de139752ae30104382d0bd5e0af1d5019e12929 Mon Sep 17 00:00:00 2001 From: Neil Lindquist Date: Sat, 22 Dec 2018 19:50:31 -0600 Subject: [PATCH 6/6] Add message for errors in returning from frame --- lib/atom-slime-frame-info.coffee | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/atom-slime-frame-info.coffee b/lib/atom-slime-frame-info.coffee index 0f89466..5be9dcd 100644 --- a/lib/atom-slime-frame-info.coffee +++ b/lib/atom-slime-frame-info.coffee @@ -71,7 +71,9 @@ class FrameInfoView extends ScrollView @returnFromFrame.on 'click', (event) => @debugView.active = false - @swank.debug_return_from_frame(@frame_index, @frameReturnValue[0].value, @info.thread) + @swank.debug_return_from_frame(@frame_index, @frameReturnValue.val(), @info.thread) + .catch (errorMessage) => + atom.notifications.addError(errorMessage) @evalInFrame.on 'click', (event) => input = @frameReturnValue.val()