From ca0f86a37c26dedd5425e7ed997b632f9b5e7b5c Mon Sep 17 00:00:00 2001 From: gentoo90 Date: Sat, 10 Jun 2017 14:55:41 +0300 Subject: [PATCH] Don't swallow errors on varUpdate() Add MIError class for exceptions. Check error type on varUpdate() failure and rethrow if it's not "Variable object not found". --- src/backend/backend.ts | 35 +++++++++++++++++++++++++++++++++++ src/backend/mi2/mi2.ts | 6 +++--- src/mibase.ts | 15 ++++++++++----- 3 files changed, 48 insertions(+), 8 deletions(-) diff --git a/src/backend/backend.ts b/src/backend/backend.ts index d85cd26..1a04c7b 100644 --- a/src/backend/backend.ts +++ b/src/backend/backend.ts @@ -123,3 +123,38 @@ export class VariableObject { return res; } } + +// from https://gist.github.com/justmoon/15511f92e5216fa2624b#gistcomment-1928632 +export interface MIError extends Error { + readonly name: string; + readonly message: string; + readonly source: string; +}; +export interface MIErrorConstructor { + new (message: string, source: string): MIError; + readonly prototype: MIError; +} + +export const MIError: MIErrorConstructor = class MIError { + readonly name: string; + readonly message: string; + readonly source: string; + public constructor(message: string, source: string) { + Object.defineProperty(this, 'name', { + get: () => (this.constructor as any).name, + }); + Object.defineProperty(this, 'message', { + get: () => message, + }); + Object.defineProperty(this, 'source', { + get: () => source, + }); + Error.captureStackTrace(this, this.constructor); + } + + public toString() { + return `${this.message} (from ${this.source})`; + } +}; +Object.setPrototypeOf(MIError as any, Object.create(Error.prototype)); +MIError.prototype.constructor = MIError; diff --git a/src/backend/mi2/mi2.ts b/src/backend/mi2/mi2.ts index 9a89594..18f45fb 100644 --- a/src/backend/mi2/mi2.ts +++ b/src/backend/mi2/mi2.ts @@ -1,4 +1,4 @@ -import { Breakpoint, IBackend, Stack, SSHArguments, Variable, VariableObject } from "../backend" +import { Breakpoint, IBackend, Stack, SSHArguments, Variable, VariableObject, MIError } from "../backend" import * as ChildProcess from "child_process" import { EventEmitter } from "events" import { parseMI, MINode } from '../mi_parse'; @@ -729,11 +729,11 @@ export class MI2 extends EventEmitter implements IBackend { this.handlers[sel] = (node: MINode) => { if (node && node.resultRecords && node.resultRecords.resultClass === "error") { if (suppressFailure) { - this.log("stderr", "WARNING: Error executing command '" + command + "'"); + this.log("stderr", `WARNING: Error executing command '${command}'`); resolve(node); } else - reject((node.result("msg") || "Internal error") + " (from " + command + ")"); + reject(new MIError(node.result("msg") || "Internal error", command)); } else resolve(node); diff --git a/src/mibase.ts b/src/mibase.ts index aaeef58..d054823 100644 --- a/src/mibase.ts +++ b/src/mibase.ts @@ -1,6 +1,6 @@ import { DebugSession, InitializedEvent, TerminatedEvent, StoppedEvent, OutputEvent, Thread, StackFrame, Scope, Source, Handles } from 'vscode-debugadapter'; import { DebugProtocol } from 'vscode-debugprotocol'; -import { Breakpoint, IBackend, Variable, VariableObject, ValuesFormattingMode } from './backend/backend'; +import { Breakpoint, IBackend, Variable, VariableObject, ValuesFormattingMode, MIError } from './backend/backend'; import { MINode } from './backend/mi_parse'; import { expandValue, isExpandable } from './backend/gdb_expansion'; import { MI2 } from './backend/mi2/mi2'; @@ -349,10 +349,15 @@ export class MI2DebugSession extends DebugSession { varObj = this.variableHandles.get(varId) as any; } catch (err) { - varObj = await this.miDebugger.varCreate(variable.name, variable.name); - const varId = findOrCreateVariable(varObj); - varObj.exp = variable.name; - varObj.id = varId; + if (err instanceof MIError && err.message == "Variable object not found") { + varObj = await this.miDebugger.varCreate(variable.name, variable.name); + const varId = findOrCreateVariable(varObj); + varObj.exp = variable.name; + varObj.id = varId; + } + else { + throw err; + } } variables.push(varObj.toProtocolVariable()); }