lib/modules/logger/usercommands/sendReport.js
function prettifyStackTrace(appName, clientConfig, stack) {
	if (!appName || !clientConfig || !Array.isArray(stack)) {
		return;
	}

	var app = mage.core.app.get(appName);
	if (!app) {
		return;
	}

	var responses = app.getResponsesForClientConfig(app.getBestConfig(clientConfig));

	// On the client side, stacktrace.js has turned each entry into "symbol@file:line:col".
	// Now try to source-map our way through it.

	function replacer(match, file, line, col) {
		line = parseInt(line, 10);
		col = parseInt(col, 10);

		for (var i = 0; i < responses.length; i++) {
			var meta = responses[i].meta;
			var sourcemap = meta && meta.sourcemaps && meta.sourcemaps[file];

			if (!sourcemap) {
				continue;
			}

			var smc = new SourceMapConsumer(sourcemap);
			var pos = smc.originalPositionFor({ line: line, column: col });

			if (pos) {
				return pos.name + ' (' + file + ':' + pos.line + ':' + pos.column + ')';
			}
		}

		return match;
	}

	for (var i = 0; i < stack.length; i++) {
		var frame = stack[i];

		if (typeof frame === 'string') {
			// rewrite the stack frame and put it back in the stack

			stack[i] = frame.replace(/^.+?@(.+?):([0-9]+):([0-9]+)$/, replacer);
		}
	}
}
function prettifyStackTrace(appName, clientConfig, stack) {
	if (!appName || !clientConfig || !Array.isArray(stack)) {
		return;
	}

	var app = mage.core.app.get(appName);
	if (!app) {
		return;
	}

	var responses = app.getResponsesForClientConfig(app.getBestConfig(clientConfig));

	// On the client side, stacktrace.js has turned each entry into "symbol@file:line:col".
	// Now try to source-map our way through it.

	function replacer(match, file, line, col) {
		line = parseInt(line, 10);
		col = parseInt(col, 10);

		for (var i = 0; i < responses.length; i++) {
			var meta = responses[i].meta;
			var sourcemap = meta && meta.sourcemaps && meta.sourcemaps[file];

			if (!sourcemap) {
				continue;
			}

			var smc = new SourceMapConsumer(sourcemap);
			var pos = smc.originalPositionFor({ line: line, column: col });

			if (pos) {
				return pos.name + ' (' + file + ':' + pos.line + ':' + pos.column + ')';
			}
		}

		return match;
	}

	for (var i = 0; i < stack.length; i++) {
		var frame = stack[i];

		if (typeof frame === 'string') {
			// rewrite the stack frame and put it back in the stack

			stack[i] = frame.replace(/^.+?@(.+?):([0-9]+):([0-9]+)$/, replacer);
		}
	}
}
function prettifyStackTrace ( appName , clientConfig , stack ) { if ( ! appName || ! clientConfig || ! Array . isArray ( stack ) ) { return ; } var app = mage . core . app . get ( appName ) ; if ( ! app ) { return ; } var responses = app . getResponsesForClientConfig ( app . getBestConfig ( clientConfig ) ) ; // On the client side, stacktrace.js has turned each entry into "symbol@file:line:col". // Now try to source-map our way through it. function replacer ( match , file , line , col ) { line = parseInt ( line , 10 ) ; col = parseInt ( col , 10 ) ; for ( var i = 0 ; i < responses . length ; i ++ ) { var meta = responses [ i ] . meta ; var sourcemap = meta && meta . sourcemaps && meta . sourcemaps [ file ] ; if ( ! sourcemap ) { continue ; } var smc = new SourceMapConsumer ( sourcemap ) ; var pos = smc . originalPositionFor ( { line : line , column : col } ) ; if ( pos ) { return pos . name + ' (' + file + ':' + pos . line + ':' + pos . column + ')' ; } } return match ; } for ( var i = 0 ; i < stack . length ; i ++ ) { var frame = stack [ i ] ; if ( typeof frame === 'string' ) { // rewrite the stack frame and put it back in the stack stack [ i ] = frame . replace ( / ^.+?@(.+?):([0-9]+):([0-9]+)$ / , replacer ) ; } } }
This function depends on stack traces being formatted by the stacktrace.js library

@param {string}   appName
@param {Object}   clientConfig
@param {string[]} stack
This function depends on stack traces being formatted by the stacktrace . js library