AngularJS - 소스 맵을 무시하는 스택트레이스
나는 Angular를 썼다.JS 앱이지만 디버깅하기엔 좀 악몽같다.Grunt + uglify를 사용하여 응용 프로그램 코드를 연결하고 최소화합니다.또한 최소화된 JS 파일 옆에 소스 맵을 만듭니다.
파일에 JS 오류가 있지만 Angular를 벗어나면 소스 맵이 제대로 작동하는 것처럼 보입니다.JS 어플리케이션. 예를 들어 글을 쓰는 경우console.log('a.b');
Chrome 디버거에 기록된 오류는 최소화된 파일이 아닌 원본 파일의 줄 + 파일 정보를 표시합니다.
이 문제는 Angular가 자체적으로 실행되는 코드에 문제가 있을 때 발생합니다(예: 컨트롤러 코드).Angular에서 멋진 스택 트레이스를 받았는데, 원본이 아닌 미니화된 파일만 자세히 나와 있습니다.
Angular가 소스 맵을 확인하도록 할 수 있는 방법이 없을까요?
다음 오류 예:
TypeError: Cannot call method 'getElement' of undefined
at Object.addMapControls (http://my-site/wp-content/plugins/my-maps/assets/js/app.min.js:1:2848)
at Object.g [as init] (http://my-site/wp-content/plugins/my-maps/assets/js/app.min.js:1:344)
at new a (http://my-site/wp-content/plugins/my-maps/assets/js/app.min.js:1:591)
at d (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.0-rc.2/angular.min.js:29:495)
at Object.instantiate (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.0-rc.2/angular.min.js:30:123)
Larrifax의 답변은 좋지만, 같은 문제 보고서에 기재되어 있는 함수의 개량 버전이 있습니다.
.config(function($provide) {
// Fix sourcemaps
// @url https://github.com/angular/angular.js/issues/5217#issuecomment-50993513
$provide.decorator('$exceptionHandler', function($delegate) {
return function(exception, cause) {
$delegate(exception, cause);
setTimeout(function() {
throw exception;
});
};
});
})
Andrew Mage가 지적한 바와 같이 2개의 스택트레이스가 생성됩니다.하나는 Angular로 포맷된 후 다른 하나는 브라우저로 포맷된 것입니다.두 번째 트레이스에서는 소스 맵이 적용됩니다.중복을 비활성화하는 것은 좋은 생각이 아닙니다.다른 Angular 모듈도 이 후에 위임을 통해 호출할 수 있는 예외와 함께 작동할 수 있기 때문입니다.
내가 찾을 수 있는 유일한 해결책은 스스로 참고 소스 지도를 분석하는 것이다.이 작업을 수행할 수 있는 몇 가지 코드가 있습니다.먼저 페이지에 소스 맵을 추가해야 합니다.그런 다음 다음 코드를 추가합니다.
angular.module('Shared').factory('$exceptionHandler',
function($log, $window, $injector) {
var getSourceMappedStackTrace = function(exception) {
var $q = $injector.get('$q'),
$http = $injector.get('$http'),
SMConsumer = window.sourceMap.SourceMapConsumer,
cache = {};
// Retrieve a SourceMap object for a minified script URL
var getMapForScript = function(url) {
if (cache[url]) {
return cache[url];
} else {
var promise = $http.get(url).then(function(response) {
var m = response.data.match(/\/\/# sourceMappingURL=(.+\.map)/);
if (m) {
var path = url.match(/^(.+)\/[^/]+$/);
path = path && path[1];
return $http.get(path + '/' + m[1]).then(function(response) {
return new SMConsumer(response.data);
});
} else {
return $q.reject();
}
});
cache[url] = promise;
return promise;
}
};
if (exception.stack) { // not all browsers support stack traces
return $q.all(_.map(exception.stack.split(/\n/), function(stackLine) {
var match = stackLine.match(/^(.+)(http.+):(\d+):(\d+)/);
if (match) {
var prefix = match[1], url = match[2], line = match[3], col = match[4];
return getMapForScript(url).then(function(map) {
var pos = map.originalPositionFor({
line: parseInt(line, 10),
column: parseInt(col, 10)
});
var mangledName = prefix.match(/\s*(at)?\s*(.*?)\s*(\(|@)/);
mangledName = (mangledName && mangledName[2]) || '';
return ' at ' + (pos.name ? pos.name : mangledName) + ' ' +
$window.location.origin + pos.source + ':' + pos.line + ':' +
pos.column;
}, function() {
return stackLine;
});
} else {
return $q.when(stackLine);
}
})).then(function (lines) {
return lines.join('\n');
});
} else {
return $q.when('');
}
};
return function(exception) {
getSourceMappedStackTrace(exception).then($log.error);
};
});
이 코드는 소스를 다운로드한 후 소스 맵을 다운로드하여 해석하고 마지막으로 스택 내의 위치 교환을 시도하여 매핑된 위치를 추적합니다.이 기능은 Chrome에서 완벽하게 작동하며 Firefox에서도 충분히 사용할 수 있습니다.단점은 코드베이스에 상당히 큰 의존관계를 추가하고 매우 빠른 동기 오류 보고에서 상당히 느린 비동기 오류 보고로 이행한다는 것입니다.
같은 문제를 안고 해결책을 찾고 있었습니다.일반적으로 스택트레이스의 크롬 문제이고 에러 리포트에 스택트레이스를 사용하기 때문에 Angular에 적용됩니다.참조:
Google Chrome의 소스 매핑이 Error.stack에 푸시됩니까?
다음 프로젝트를 보겠습니다.https://github.com/novocaine/sourcemapped-stacktrace
기본적으로는 @jakub-hampl의 답변과 동일하지만 유용할 수 있습니다.
이번 호를 보면 앵귤러 형제는$logProvider
소스 매핑이 끊어집니다. 방법이 되어 있습니다.
var module = angular.module('source-map-exception-handler', [])
module.config(function($provide) {
$provide.decorator('$exceptionHandler', function($delegate) {
return function(exception, cause) {
$delegate(exception, cause);
throw exception;
};
});
});
Chrome에서는 버그가 수정되었지만, Angular에서는 문제가 해결되지 않기 때문에 스택 트레이스를 2회 인쇄하지 않는 회피책은 다음과 같습니다.
app.factory('$exceptionHandler', function() {
return function(exception, cause) {
console.error(exception.stack);
};
});
언급URL : https://stackoverflow.com/questions/19420604/angularjs-stack-trace-ignoring-source-map
'sourcecode' 카테고리의 다른 글
워드프레스:$wpdb->get_results를 사용할 때 결과를 이스케이프 해제하려면 어떻게 해야 합니까? (0) | 2023.02.15 |
---|---|
선택한 ng-option이 변경될 때 값 가져오기 (0) | 2023.02.15 |
react-testing-library는 왜 ToBeInThe Document() (0) | 2023.02.15 |
Wordpress 테마 업로드 오류 PCLZIP_ERR_BAD_포맷 (0) | 2023.02.15 |
WordPress에 체크박스 메타박스를 저장하는 방법 (0) | 2023.02.15 |