Skip to content
This repository has been archived by the owner on Oct 2, 2021. It is now read-only.

Commit

Permalink
Implement ExceptionInfoRequest - Fix #191
Browse files Browse the repository at this point in the history
  • Loading branch information
roblourens committed Mar 24, 2017
1 parent 2643d48 commit febd189
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 4 deletions.
31 changes: 27 additions & 4 deletions src/chrome/chromeDebugAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {InitializedEvent, TerminatedEvent, Handles, ContinuedEvent, BreakpointEv
import {ICommonRequestArgs, ILaunchRequestArgs, ISetBreakpointsArgs, ISetBreakpointsResponseBody, IStackTraceResponseBody,
IAttachRequestArgs, IScopesResponseBody, IVariablesResponseBody,
ISourceResponseBody, IThreadsResponseBody, IEvaluateResponseBody, ISetVariableResponseBody, IDebugAdapter,
ICompletionsResponseBody, IToggleSkipFileStatusArgs, IInternalStackTraceResponseBody, ILoadedScript, IAllLoadedScriptsResponseBody} from '../debugAdapterInterfaces';
ICompletionsResponseBody, IToggleSkipFileStatusArgs, IInternalStackTraceResponseBody, ILoadedScript, IAllLoadedScriptsResponseBody, IExceptionInfoResponseBody} from '../debugAdapterInterfaces';
import {IChromeDebugAdapterOpts, ChromeDebugSession} from './chromeDebugSession';
import {ChromeConnection} from './chromeConnection';
import * as ChromeUtils from './chromeUtils';
Expand Down Expand Up @@ -183,7 +183,8 @@ export abstract class ChromeDebugAdapter implements IDebugAdapter {
supportsConditionalBreakpoints: true,
supportsCompletionsRequest: true,
supportsHitConditionalBreakpoints: true,
supportsRestartFrame: true
supportsRestartFrame: true,
supportsExceptionInfoRequest: true
};
}

Expand Down Expand Up @@ -414,6 +415,27 @@ export abstract class ChromeDebugAdapter implements IDebugAdapter {
}).catch(err => logger.error('Problem while smart stepping: ' + (err && err.stack) ? err.stack : err));
}

public exceptionInfo(args: DebugProtocol.ExceptionInfoArguments): IExceptionInfoResponseBody {
if (args.threadId !== ChromeDebugAdapter.THREAD_ID) {
throw errors.invalidThread(args.threadId);
}

if (this._exception) {
const response: IExceptionInfoResponseBody = {
exceptionId: this._exception.className,
description: utils.firstLine(this._exception.description),
breakMode: 'unhandled',
details: {
stackTrace: this._exception.description
}
};

return response;
} else {
throw errors.noStoredException();
}
}

private async shouldSmartStep(frame: Crdp.Debugger.CallFrame): Promise<boolean> {
if (!this.smartStepEnabled()) return Promise.resolve(false);

Expand Down Expand Up @@ -761,9 +783,10 @@ export abstract class ChromeDebugAdapter implements IDebugAdapter {
const lineNum = parseInt(matches[3], 10);
const columnNum = parseInt(matches[4], 10);
const clientPath = this._pathTransformer.getClientPathFromTargetPath(path);
const mapped = await this._sourceMapTransformer.mapToAuthored(clientPath || path, lineNum, columnNum);
const mapped = await this._sourceMapTransformer.mapToAuthored(clientPath || path, lineNum - 1, columnNum);

if (mapped && mapped.source && mapped.line && mapped.column) {
if (mapped && mapped.source && utils.isNumber(mapped.line) && utils.isNumber(mapped.column)) {
this._lineColTransformer.mappedExceptionStack(mapped);
exceptionLines[i] = exceptionLines[i].replace(
`${path}:${lineNum}:${columnNum}`,
`${mapped.source}:${mapped.line}:${mapped.column}`
Expand Down
11 changes: 11 additions & 0 deletions src/debugAdapterInterfaces.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,17 @@ export interface IAllLoadedScriptsResponseBody {
loadedScripts: ILoadedScript[];
}

export interface IExceptionInfoResponseBody {
/** ID of the exception that was thrown. */
exceptionId: string;
/** Descriptive text for the exception provided by the debug adapter. */
description?: string;
/** Mode that caused the exception notification to be raised. */
breakMode: DebugProtocol.ExceptionBreakMode;
/** Detailed information about the exception. */
details?: DebugProtocol.ExceptionDetails;
}

declare type PromiseOrNot<T> = T | Promise<T>;

/**
Expand Down
25 changes: 25 additions & 0 deletions src/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,28 @@ export function noCallStackAvailable(): DebugProtocol.Message {
format: localize('VSND2023', "No call stack available.")
};
}

export function invalidThread(threadId: number): DebugProtocol.Message {
return {
id: 2030,
format: 'Invalid thread {_thread}',
variables: { _thread: threadId + '' },
sendTelemetry: true
};
}

export function exceptionInfoRequestError(): DebugProtocol.Message {
return {
id: 2031,
format: 'exceptionInfoRequest error',
sendTelemetry: true
};
}

export function noStoredException(): DebugProtocol.Message {
return {
id: 2032,
format: 'exceptionInfoRequest error: no stored exception',
sendTelemetry: true
};
}
4 changes: 4 additions & 0 deletions src/transformers/lineNumberTransformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ export class LineColTransformer implements IDebugTransformer {
scopeResponse.scopes.forEach(scope => this.mapScopeLocations(scope));
}

public mappedExceptionStack(location: { line: number; column: number }): void {
this.convertDebuggerLocationToClient(location);
}

private mapScopeLocations(scope: DebugProtocol.Scope): void {
this.convertDebuggerLocationToClient(scope);

Expand Down
4 changes: 4 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -515,4 +515,8 @@ export function getLine(msg: string, n = 0): string {

export function firstLine(msg: string): string {
return getLine(msg);
}

export function isNumber(num: number): boolean {
return typeof num === 'number';
}

0 comments on commit febd189

Please sign in to comment.