>  기사  >  웹 프론트엔드  >  JavaScript 예외 처리 상세 설명_javascript 기술

JavaScript 예외 처리 상세 설명_javascript 기술

WBOY
WBOY원래의
2016-05-16 16:15:30903검색

프론트엔드 엔지니어들은 모두 JavaScript에 기본적인 예외 처리 기능이 있다는 것을 알고 있습니다. new Error()를 던질 수 있고, API를 호출할 때 오류가 발생하면 브라우저도 예외를 던질 것입니다. 하지만 대부분의 프론트엔드 엔지니어들은 이러한 비정상적인 정보 수집을 고려한 적이 없는 것으로 추정됩니다

어쨌든 새로 고침 후에도 JavaScript 오류가 다시 나타나지 않는 한 사용자는 새로 고침을 통해 문제를 해결할 수 있으며 브라우저는 충돌이 발생하지 않은 것처럼 행동합니다. 이 가정은 단일 페이지 앱이 대중화되기 전에는 사실이었습니다. 현재 단일 페이지 앱의 상태는 일정 기간 동안 실행된 후 매우 복잡해집니다. 사용자가 여기에 도착하기 전에 여러 가지 입력 작업을 수행했을 수 있습니다. 새로 고쳐진다고 하면 새로 고쳐야 할까요? 이전 작업을 완전히 다시 수행해야 하는 것 아닌가요? 따라서 이러한 예외 정보를 캡처하고 분석한 다음 사용자 경험에 영향을 주지 않도록 코드를 수정할 수 있습니다.

예외를 잡는 방법

우리는 자체적으로 새로운 Throw Error()를 작성했습니다. 물론 우리는 throw가 어디에 기록되었는지 정확히 알고 있기 때문에 원할 경우 이를 잡을 수 있습니다. 그러나 브라우저 API를 호출할 때 발생하는 예외는 반드시 잡기 쉬운 것은 아닙니다. 일부 API는 예외를 발생시키도록 표준에 작성되어 있으며, 일부 API는 구현 차이 또는 결함으로 인해 개별 브라우저에서만 발생합니다. 전자의 경우 try-catch를 통해 이를 포착할 수도 있습니다. 후자의 경우 전역 예외를 수신한 다음 이를 포착해야 합니다.

시도

일부 브라우저 API가 예외를 발생시키는 것으로 알려진 경우 전체 프로그램이 오류로 인해 잘못된 상태로 들어가는 것을 방지하기 위해 호출을 try-catch에 넣어야 합니다. 예를 들어, window.localStorage는 데이터 쓰기가 용량 제한을 초과하면 예외를 발생시킵니다. 이는 Safari의 개인 탐색 모드에서도 마찬가지입니다.

코드 복사 코드는 다음과 같습니다.

시도해보세요 {
localStorage.setItem('date', Date.now());
} 잡기(오류) {
보고오류(오류);
}


try-catch의 또 다른 일반적인 사용 사례는 콜백입니다. 콜백 함수의 코드는 우리가 통제할 수 없기 때문에 코드의 품질이나 예외를 발생시키는 다른 API가 호출되는지 여부에 대해 알 수 없습니다. 콜백을 호출한 후 다른 코드가 콜백 오류로 인해 실행되지 않는 것을 방지하려면 콜백을 try-catch에 다시 넣어야 합니다.

코드 복사 코드는 다음과 같습니다.

Listeners.forEach(함수(리스너) {
시도해보세요 {
리스너();
} 잡기(오류) {
보고오류(오류);
}
});


window.onerror

try-catch가 적용되지 않는 영역의 경우 예외가 발생하면 window.onerror를 통해서만 catch할 수 있습니다.

코드 복사 코드는 다음과 같습니다.

window.onerror =
함수(errorMessage, scriptURI, lineNumber) {
보고오류({
메시지: errorMessage,
스크립트: scriptURI,
줄: 줄번호
});
}


영리하게 행동하지 않도록 주의하고 window.addEventListener 또는 window.attachEvent를 사용하여 window.onerror를 수신하세요. 많은 브라우저에서는 window.onerror만 구현하거나 window.onerror 구현만 표준입니다. 표준 초안에서도 window.onerror를 정의하고 있다는 점을 고려하면 그냥 window.onerror를 사용해도 됩니다.

속성 상실

캡처된 예외를 수집한 다음 쿼리 및 분석을 위해 일괄적으로 서버 측 저장소로 보내는 reportError 함수가 있다고 가정해 보겠습니다. 더 유용한 정보에는 오류 유형(이름), 오류 메시지(메시지), 스크립트 파일 주소(script), 줄 번호(line), 열 번호(column) 및 스택 추적(stack)이 포함됩니다. try-catch를 통해 예외가 포착되면 이 정보는 Error 개체(주요 브라우저에서 지원됨)에 있으므로 reportError도 이 정보를 수집할 수 있습니다. 하지만 window.onerror를 통해 캡처하면 이 이벤트 함수에는 3개의 매개변수만 있으므로 이 3개의 매개변수에 대한 예상치 못한 정보가 손실된다는 것을 우리 모두 알고 있습니다.

직렬화된 메시지

Error 객체가 스스로 생성된 경우 error.message는 우리가 제어합니다. 기본적으로 우리가 error.message에 무엇을 입력하든 window.onerror의 첫 번째 매개변수(메시지)가 됩니다. (브라우저는 실제로 'Uncaught Error:' 접두사를 추가하는 등 약간의 수정을 합니다.) 따라서 우리가 관심 있는 속성(예: JSON.Stringify)을 직렬화하고 이를 error.message에 저장한 다음 읽을 수 있습니다. window.onerror에서 꺼내서 역직렬화하세요. 물론 이는 우리가 직접 생성한 Error 개체로 제한됩니다.

다섯 번째 매개변수

브라우저 제조업체도 window.onerror를 사용할 때 사람들이 직면하는 한계를 알고 있기 때문에 window.onerror에 새로운 매개변수를 추가하기 시작했습니다. 행 번호만 있고 열 번호가 없는 것을 고려하여 IE는 먼저 열 번호를 추가하고 이를 네 번째 매개 변수에 넣습니다. 그러나 모든 사람들은 완전한 스택을 얻을 수 있는지에 대해 더 관심을 갖고 있으므로 Firefox는 스택을 다섯 번째 매개 변수에 넣는 것이 더 나을 것이라고 말했습니다. 하지만 Chrome에서는 전체 Error 개체를 다섯 번째 매개변수에 넣는 것이 더 낫다고 말했습니다. 맞춤 속성을 포함하여 원하는 모든 속성을 읽을 수 있습니다. 결과적으로 Chrome은 더 빠르게 움직이고 Chrome 30에서 새로운 window.onerror 서명을 구현하여 이에 따라 표준 초안이 작성되었습니다.

코드 복사 코드는 다음과 같습니다.

window.onerror = 함수(
오류 메시지,
스크립트URI,
라인번호,
열번호,
오류
) {
if (오류) {
보고오류(오류);
} 그 밖의 {
보고오류({
메시지: errorMessage,
스크립트: scriptURI,
줄: 줄번호,
열: 열번호
});
}
}


속성 정규화

앞서 논의한 Error 개체 속성의 이름은 Chrome의 명명 방법을 기반으로 합니다. 그러나 브라우저마다 Error 개체 속성의 이름을 다르게 지정합니다. 예를 들어 스크립트 파일 주소는 Chrome에서는 script라고 부르지만 Firefox에서는 filename이라고 합니다. . 따라서 Error 객체를 정규화하는, 즉 서로 다른 속성 이름을 통합된 속성 이름에 매핑하는 특수 함수도 필요합니다. 구체적인 방법은 이 글을 참고하세요. 브라우저 구현이 업데이트되더라도 이러한 매핑 테이블을 수동으로 유지 관리하는 것은 그리 어렵지 않습니다.

스택 추적 형식과 유사합니다. 이 속성은 예외 정보 스택을 일반 텍스트 형식으로 저장합니다. 각 브라우저에서 사용하는 텍스트 형식이 다르기 때문에 일반 텍스트에서 각 프레임의 기능을 추출하려면 정규식을 수동으로 유지해야 합니다. 식별자), 파일(스크립트), 줄 번호(line) 및 열 번호(열)입니다.

보안 제한

'스크립트 오류' 메시지와 함께 오류가 발생했다면 제가 말하는 내용을 이해하실 것입니다. 이는 실제로 다른 출처의 스크립트 파일에 대한 브라우저 제한 사항입니다. 이러한 보안 제한의 이유는 사용자가 로그인한 후 온라인 은행에서 반환한 HTML이 익명 사용자가 본 HTML과 다르다고 가정하면 제3자 웹사이트에서 온라인 은행의 URI를 스크립트에 넣을 수 있기 때문입니다. src 속성. 물론 HTML은 JS로 구문 분석할 수 없으므로 브라우저에서는 예외가 발생하며, 타사 웹사이트에서는 예외 위치를 구문 분석하여 사용자가 로그인했는지 여부를 확인할 수 있습니다. 이러한 이유로 브라우저는 '스크립트 오류'와 같은 변경되지 않은 메시지가 하나만 남고 다른 모든 속성이 사라질 때까지 다양한 소스의 스크립트 파일에서 발생하는 모든 예외를 필터링합니다.

특정 규모의 웹사이트의 경우 스크립트 파일이 다양한 소스의 CDN에 배치되는 것이 일반적입니다. 이제 자신만의 작은 웹사이트를 구축하더라도 jQuery 및 Backbone과 같은 일반적인 프레임워크는 공개 CDN의 버전을 직접 참조하여 사용자 다운로드 속도를 높일 수 있습니다. 따라서 이러한 보안 제한은 일부 문제를 야기하여 Chrome 및 Firefox에서 수집한 예외 정보가 쓸모없는 '스크립트 오류'가 되도록 만듭니다.

코르스

이 제한을 우회하려면 스크립트 파일과 페이지 자체의 출처가 동일한지 확인하세요. 그런데 CDN으로 가속되지 않는 서버에 스크립트 파일을 놓으면 사용자의 다운로드 속도가 느려지지 않나요? 한 가지 해결 방법은 계속해서 CDN에 스크립트 파일을 배치하고 XMLHttpRequest를 사용하여 CORS를 통해 콘텐츠를 다시 다운로드한 다음