@@ -67,6 +67,12 @@ class AppInspector extends Domain {
6767 final String _root;
6868 final SdkConfiguration _sdkConfiguration;
6969
70+ /// JavaScript expression that evaluates to the Dart stack trace mapper.
71+ static const stackTraceMapperExpression = '\$ dartStackTraceUtility.mapper' ;
72+
73+ /// Regex used to extract the message from an exception description.
74+ static final exceptionMessageRegex = RegExp (r'^.*$' , multiLine: true );
75+
7076 AppInspector ._(
7177 this .appConnection,
7278 this .isolate,
@@ -223,7 +229,7 @@ class AppInspector extends Domain {
223229 /// [evalExpression] should be a JS function definition that can accept
224230 /// [arguments] .
225231 Future <RemoteObject > _jsCallFunction (
226- String evalExpression, List <RemoteObject > arguments,
232+ String evalExpression, List <Object > arguments,
227233 {bool returnByValue = false }) async {
228234 var jsArguments = arguments.map (callArgumentFor).toList ();
229235 var result =
@@ -550,4 +556,23 @@ function($argsString) {
550556 handleErrorIfPresent (extensionsResult, evalContents: expression);
551557 return List .from (extensionsResult.result['result' ]['value' ] as List );
552558 }
559+
560+ /// Convert a JS exception description into a description containing
561+ /// a Dart stack trace.
562+ Future <String > mapExceptionStackTrace (String description) async {
563+ RemoteObject mapperResult;
564+ try {
565+ mapperResult = await _jsCallFunction (
566+ stackTraceMapperExpression, < Object > [description]);
567+ } catch (_) {
568+ return description;
569+ }
570+ var mappedStack = mapperResult? .value? .toString ();
571+ if (mappedStack == null || mappedStack.isEmpty) {
572+ return description;
573+ }
574+ var message = exceptionMessageRegex.firstMatch (description)? .group (0 );
575+ message = (message != null ) ? '$message \n ' : '' ;
576+ return '$message $mappedStack ' ;
577+ }
553578}
0 commit comments