debugger: Show errors loading stack (#32658)
- **TEMP** - **Show errors loading stack frames** - **Stop cloning every DAP response unnecessarily** Closes #ISSUE Release Notes: - debugger: Show errors loading stack frames. <img width="1840" alt="Screenshot 2025-06-12 at 23 53 42" src="https://github.com/user-attachments/assets/310d3046-f34c-4964-acef-f9742441c9db" />
This commit is contained in:
parent
bcd79331b9
commit
f63ae4388d
2 changed files with 123 additions and 86 deletions
|
@ -36,6 +36,7 @@ pub struct StackFrameList {
|
|||
opened_stack_frame_id: Option<StackFrameId>,
|
||||
scrollbar_state: ScrollbarState,
|
||||
list_state: ListState,
|
||||
error: Option<SharedString>,
|
||||
_refresh_task: Task<()>,
|
||||
}
|
||||
|
||||
|
@ -82,6 +83,7 @@ impl StackFrameList {
|
|||
state,
|
||||
_subscription,
|
||||
entries: Default::default(),
|
||||
error: None,
|
||||
selected_ix: None,
|
||||
opened_stack_frame_id: None,
|
||||
list_state,
|
||||
|
@ -113,21 +115,19 @@ impl StackFrameList {
|
|||
.collect::<Vec<_>>()
|
||||
}
|
||||
|
||||
fn stack_frames(&self, cx: &mut App) -> Vec<StackFrame> {
|
||||
self.state
|
||||
.read_with(cx, |state, _| state.thread_id)
|
||||
.ok()
|
||||
.flatten()
|
||||
.map(|thread_id| {
|
||||
self.session
|
||||
.update(cx, |this, cx| this.stack_frames(thread_id, cx))
|
||||
})
|
||||
.unwrap_or_default()
|
||||
fn stack_frames(&self, cx: &mut App) -> Result<Vec<StackFrame>> {
|
||||
if let Ok(Some(thread_id)) = self.state.read_with(cx, |state, _| state.thread_id) {
|
||||
self.session
|
||||
.update(cx, |this, cx| this.stack_frames(thread_id, cx))
|
||||
} else {
|
||||
Ok(Vec::default())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) fn dap_stack_frames(&self, cx: &mut App) -> Vec<dap::StackFrame> {
|
||||
self.stack_frames(cx)
|
||||
.unwrap_or_default()
|
||||
.into_iter()
|
||||
.map(|stack_frame| stack_frame.dap.clone())
|
||||
.collect()
|
||||
|
@ -149,7 +149,7 @@ impl StackFrameList {
|
|||
let debounce = this
|
||||
.update(cx, |this, cx| {
|
||||
let new_stack_frames = this.stack_frames(cx);
|
||||
new_stack_frames.is_empty() && !this.entries.is_empty()
|
||||
new_stack_frames.unwrap_or_default().is_empty() && !this.entries.is_empty()
|
||||
})
|
||||
.ok()
|
||||
.unwrap_or_default();
|
||||
|
@ -185,7 +185,18 @@ impl StackFrameList {
|
|||
let mut first_stack_frame = None;
|
||||
let mut first_not_subtle_frame = None;
|
||||
|
||||
let stack_frames = self.stack_frames(cx);
|
||||
let stack_frames = match self.stack_frames(cx) {
|
||||
Ok(stack_frames) => stack_frames,
|
||||
Err(e) => {
|
||||
self.error = Some(format!("{}", e).into());
|
||||
self.entries.clear();
|
||||
self.selected_ix = None;
|
||||
self.list_state.reset(0);
|
||||
cx.emit(StackFrameListEvent::BuiltEntries);
|
||||
cx.notify();
|
||||
return;
|
||||
}
|
||||
};
|
||||
for stack_frame in &stack_frames {
|
||||
match stack_frame.dap.presentation_hint {
|
||||
Some(dap::StackFramePresentationHint::Deemphasize) => {
|
||||
|
@ -212,8 +223,7 @@ impl StackFrameList {
|
|||
if !collapsed_entries.is_empty() {
|
||||
entries.push(StackFrameEntry::Collapsed(collapsed_entries.clone()));
|
||||
}
|
||||
|
||||
std::mem::swap(&mut self.entries, &mut entries);
|
||||
self.entries = entries;
|
||||
|
||||
if let Some(ix) = first_not_subtle_frame
|
||||
.or(first_stack_frame)
|
||||
|
@ -657,7 +667,7 @@ impl StackFrameList {
|
|||
}
|
||||
|
||||
fn render_list(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
|
||||
list(self.list_state.clone()).size_full()
|
||||
div().p_1().child(list(self.list_state.clone()).size_full())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -666,12 +676,27 @@ impl Render for StackFrameList {
|
|||
div()
|
||||
.track_focus(&self.focus_handle)
|
||||
.size_full()
|
||||
.p_1()
|
||||
.on_action(cx.listener(Self::select_next))
|
||||
.on_action(cx.listener(Self::select_previous))
|
||||
.on_action(cx.listener(Self::select_first))
|
||||
.on_action(cx.listener(Self::select_last))
|
||||
.on_action(cx.listener(Self::confirm))
|
||||
.when_some(self.error.clone(), |el, error| {
|
||||
el.child(
|
||||
h_flex()
|
||||
.bg(cx.theme().status().warning_background)
|
||||
.border_b_1()
|
||||
.border_color(cx.theme().status().warning_border)
|
||||
.pl_1()
|
||||
.child(Icon::new(IconName::Warning).color(Color::Warning))
|
||||
.gap_2()
|
||||
.child(
|
||||
Label::new(error)
|
||||
.size(LabelSize::Small)
|
||||
.color(Color::Warning),
|
||||
),
|
||||
)
|
||||
})
|
||||
.child(self.render_list(window, cx))
|
||||
.child(self.render_vertical_scrollbar(cx))
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue