Table des matières
相对友好但糟糕的处理方式
unhandledrejection 事件获取 Promise 错误
Maison interface Web js tutoriel Analyse des exceptions d'erreur en JavaScript (avec exemples)

Analyse des exceptions d'erreur en JavaScript (avec exemples)

Apr 04, 2019 am 11:22 AM
error javascript 异常处理 错误

Le contenu de cet article concerne l'analyse des erreurs et des exceptions en JavaScript (avec des exemples). Il a une certaine valeur de référence. J'espère qu'il sera utile. vous. aider.

Mon conseil est de ne pas cacher vos erreurs, d'être assez courageux pour les rejeter. Personne ne devrait avoir honte si un bug dans le code provoque le crash du programme. Nous pouvons interrompre le programme et laisser l'utilisateur recommencer. Les erreurs sont inévitables, ce qui compte, c'est la façon dont vous les gérez.

JavaScript fournit un mécanisme de gestion des erreurs. Les erreurs sont des accidents anormaux qui interfèrent avec le déroulement normal du programme. Et personne ne peut maintenir le programme sans bug. Alors, si vous rencontrez un bug spécial après une connexion en ligne, comment pouvez-vous localiser le problème plus rapidement ? C’est ce dont notre sujet doit discuter.

Ce qui suit décrira les connaissances de base des erreurs JavaScript, comment intercepter et capturer les exceptions et comment signaler facilement les erreurs en ligne. J'ai également fait un résumé et une analyse basés sur les points de connaissance sur Internet (je le suis. juste un porteur d'Internet) (travailleur, pas créateur)), s'il y a des erreurs ou des omissions, merci de me critiquer sévèrement sur la question.

Ce sujet s'adresse actuellement aux navigateurs, et node.js n'a pas été pris en compte. Cependant, ce sont tous de la syntaxe JavaScript Es6, qui est plus ou moins la même.

Quand JavaScript génère-t-il une erreur ?

Généralement divisé en deux situations :

Erreurs intégrées JavaScript

Erreurs activement générées par les développeurs

Moteur JavaScript automatiquement généré erreurs

Les erreurs que nous rencontrons dans la plupart des scénarios sont ce type d'erreurs. Si une erreur de syntaxe Javscript, une erreur de référence de code, une erreur de type, etc. se produit, le moteur JavaScript déclenchera automatiquement ces erreurs. Certains scénarios sont les suivants :

Scénario 1

console.log(a.notExited)
// 浏览器会抛出 Uncaught ReferenceError: a is not defined
Copier après la connexion

Scénario 2

const a;
// 浏览器抛出 Uncaught SyntaxError: Missing initializer in const declaration
Copier après la connexion

Erreur de syntaxe génère généralement une erreur immédiatement et n'attend pas l'exécution. L'erreur sera signalée lorsque .

Scénario 3

let data;
data.forEach(v=>{})
// Uncaught TypeError: Cannot read property 'forEach' of undefined
Copier après la connexion

Les erreurs générées manuellement

sont généralement des exceptions d'erreur personnalisées développées par des bibliothèques de classes (telles que des paramètres et d'autres exceptions d'erreur illégales levées). Ou modifiez à nouveau le message d'erreur et signalez-le pour faciliter la compréhension.

Scénario 1

function sum(a,b){
  if(typeof a !== 'number') {
    throw TypeError('Expected a to be a number.');
  }
  if(typeof b !== 'number') {
    throw TypeError('Expected b to be a number.');
  }
  return a + b;
}
sum(3,'d');
// 浏览器抛出 uncaught TypeError: Expected b to be a number.
Copier après la connexion

Scénario 2

Bien sûr, nous n'avons pas nécessairement besoin de faire cela.

let data;

try {
  data.forEach(v => {});
} catch (error) {
  error.message = 'data 没有定义,data 必须是数组。';
  error.name = 'DataTypeError';
  throw error;
}
Copier après la connexion

Comment créer un objet Erreur ?

La syntaxe de création est la suivante :

new Error([message[,fileName,lineNumber]])
Copier après la connexion

Il en va de même pour l'omission de la nouvelle syntaxe.

Le fileName et le lineNumber ne sont pas compatibles avec tous les navigateurs et Google ne les prend pas en charge, ils peuvent donc être ignorés.

Le constructeur Error est un type d'erreur général. En plus du type Error, il existe également TypeError, RangeError et d'autres types.

Instance d'erreur

Toutes les propriétés et méthodes de la chaîne de prototypes répertoriées ici ne sont pas expliquées. Certaines propriétés et méthodes compatibles et peu courantes ne sont pas expliquées.

console.log(Error.prototype)
// 浏览器输出 {constructor: ƒ, name: "Error", message: "", toString: ƒ}
Copier après la connexion

D'autres constructeurs de types d'erreur héritent de Error et les instances sont cohérentes.

Attributs

Error.prototype.message

Message d'erreur, Error("msg").message === "msg".

Error.prototype.name

Type d'erreur (nom), Error("msg").name === "Erreur". Si TypeError, alors le nom est TypeError.

Error.prototype.stack

L'objet Error fournit une méthode de traçage de fonction en tant qu'attribut de pile non standard. Quel que soit le mode à partir duquel cette fonction est appelée, à partir de quelle ligne ou fichier et avec quels paramètres. Cette pile est générée à partir du premier appel récent, renvoyant l'appel de portée globale d'origine.

Ceci n'est pas une spécification, il y a une compatibilité. Après tests, Google, Firefox, Edge et Safari prennent tous en charge cette fonctionnalité (tous testés sous la dernière version 2019-04-02), mais IE ne la prend pas en charge.

Méthode

Error.prototype.constructor

Error.prototype.toString

Le format de la valeur de retour est ${name} : ${message}.

Types d'erreur couramment utilisés

En plus du constructeur d'erreur général, JavaScript possède également 5 autres types courants de constructeurs d'erreur.

TypeError

Crée une instance d'Erreur indiquant la cause de l'erreur : la variable ou le paramètre n'appartient pas à un type valide.

throw TypeError("类型错误");
// Uncaught TypeError: 类型错误
Copier après la connexion

RangeError

Créez une instance d'Erreur pour indiquer la cause de l'erreur : une variable ou un paramètre numérique dépasse sa plage valide.

throw RangeError("数值超出有效范围");
// Uncaught RangeError: 数值超出有效范围
Copier après la connexion

ReferenceError

Crée une instance d'Erreur, indiquant la cause de l'erreur : référence invalide.

throw ReferenceError("无效引用");
// Uncaught ReferenceError: 无效引用
Copier après la connexion

SyntaxError

Crée une instance d'Erreur, indiquant la cause de l'erreur : erreur de syntaxe. Ce scénario est rarement utilisé, sauf si la bibliothèque de classes définit une nouvelle syntaxe (telle qu'une syntaxe de modèle).

throw SyntaxError("语法错误");
// Uncaught SyntaxError: 语法错误
Copier après la connexion

URIError

Créez une instance d'Erreur pour indiquer la cause de l'erreur : les erreurs liées à l'uri.

throw URIError("url 不合法");
// Uncaught RangeError: url 不合法
Copier après la connexion

自定义 Error 类型

自定义新的 Error 类型需要继承 Error ,如下自定义 CustomError:

function CustomError(...args){
  class InnerCustomError extends Error {
    name = "CustomError";
  }
  return new InnerCustomError(...args);
}
Copier après la connexion

继承 Error 后,我们只需要对 name 做重写,然后封装成可直接调用的函数即可。

如何拦截 JavaScript 错误?

既然没人能保证 web 应用不会出现 bug,那么出现异常报错时,如何拦截并进行一些操作呢?

try…catch… 拦截

这是拦截 JavaScript 错误,拦截后,如果不手动抛出错误,这个错误将静默处理。平常写代码如果我们知道某段代码可能会出现报错问题,就可以使用这种方式。如下:

const { data } = this.props;
try {
  data.forEach(d=>{});
  // 如果 data 不是数组就会报错
} catch(err){
  console.error(err);
  // 这里可以做上报处理等操作
}
Copier après la connexion

一些使用方式

十分不友好的处理方式

try...catch... 使用需要注意,try…catch… 后,错误会被拦截,如果不主动抛出错误,那么无法知道报错位置。如下面的处理方式就是不好的。

function badHandler(fn) {
  try {
    return fn();
  } catch (err) { /**noop,不做任何处理**/ }
  return null;
}
badHandler();
Copier après la connexion

这样 fn 回调发送错误后,我们无法知道错误是在哪里发生的,因为已经被 try…catch 了,那么如何解决这个问题呢?

相对友好但糟糕的处理方式
function CustomError(...args){
  class InnerCustomError extends Error {
    name = "CustomError";
  }
  return new InnerCustomError(...args);
}
function uglyHandlerImproved(fn) {
  try {
    return fn();
  } catch (err) { 
    throw new CustomError(err.message);
  }
  return null;
}
badHandler();
Copier après la connexion

现在,这个自定义的错误对象包含了原本错误的信息,因此变得更加有用。但是因为再度抛出来,依然是未处理的错误。

try…catch… 可以拦截异步错误吗?

这个也要分场景,也看个人的理解方向,首先理解下面这句话:

try…catch 只会拦截当前执行环境的错误,try 块中的异步已经脱离了当前的执行环境,所以 try…catch… 无效。

setTimeout 和 Promise 都无法通过 try…catch 捕获到错误,指的是 try 包含异步(非当前执行环境),不是异步包含 try(当前执行环境)。异步无效和有效 try…catch 如下:

setTimeout

这个无效:

try {
  setTimeout(() => {
    data.forEach(d => {});
  });
} catch (err) {
  console.log('这里不会运行');
}
Copier après la connexion
Copier après la connexion

下面的 try…catch 才会有效:

setTimeout(() => {
  try {
    data.forEach(d => {});
  } catch (err) {
    console.log('这里会运行');
  }
});
Copier après la connexion
Copier après la connexion

Promise

这个无效:

try {
  new Promise(resolve => {
    data.forEach(d => {});
    resolve();
  });
} catch (err) {
  console.log('这里不会运行');
}
Copier après la connexion

下面的 try…catch 才会有效:

new Promise(resolve => {
  try {
    data.forEach(d => {});
  } catch (err) {
    console.log('这里会运行');
  }
});
Copier après la connexion

小结

不是所有场景都需要 try…catch… 的,如果所有需要的地方都 try…catch,那么代码将变得臃肿,可读性变差,开发效率变低。那么我需要统一获取错误信息呢?有没有更好的处理方式?当然有,后续会提到。

Promise 错误拦截

Promise.prototype.catch 可以达到 try…catch 一样的效果,只要是在 Promise 相关的处理中报错,都会被 catch 到。当然如果你在相关回调函数中 try…catch,然后做了静默提示,那么也是 catch  不到的。

如下会被 catch 到:

new Promise(resolve => {
  data.forEach(v => {});
}).catch(err=>{/*这里会运行*/})
Copier après la connexion

下面的不会被 catch 到:

new Promise(resolve => {
  try {
      data.forEach(v => {});
  }catch(err){}
}).catch(err=>{/*这里不会运行*/})
Copier après la connexion

Promise 错误拦截,这里就不详细说了,如果你看懂了 try…catch,这个也很好理解。

setTimeout 等其他异步错误拦截呢?

目前没有相关的方式直接拦截 setTimeout 等其他异步操作。

如果要拦截 setTimeout 等异步错误,我们需要在异步回调代码中处理,如:

setTimeout(() => {
  try {
    data.forEach(d => {});
  } catch (err) {
    console.log('这里会运行');
  }
});
Copier après la connexion
Copier après la connexion

这样可以拦截到 setTimeout 回调发生的错误,但是如果是下面这样 try…catch 是无效的:

try {
  setTimeout(() => {
    data.forEach(d => {});
  });
} catch (err) {
  console.log('这里不会运行');
}
Copier après la connexion
Copier après la connexion

如何获取 JavaScript 错误信息?

你可以使用上面拦截错误信息的方式获取到错误信息。但是呢,你要每个场景都要去拦截一遍吗?首先我们不确定什么地方会发生错误,然后我们也不可能每个地方都去拦截错误。

不用担心,JavaScript 也考虑到了这一点,提供了一些便捷的获取方式(不是拦截,错误还是会终止程序的运行,除非主动拦截了)。

window.onerror 事件获取错误信息

onerror 事件无论是异步还是非异步错误(除了 Promise 错误),onerror 都能捕获到运行时错误。

需要注意一下几点:

window.onerror 函数只有在返回 true 的时候,异常才不会向上抛出,否则即使是知道异常的发生控制台还是会显示 Uncaught Error: xxxxx。如果使用 addEventListener,event.preventDefault() 可以达到同样的效果。

window.onerror 是无法捕获到网络异常的错误、

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Solution à l'erreur d'invite de mise à jour Windows 0x8024401c Solution à l'erreur d'invite de mise à jour Windows 0x8024401c Jun 08, 2024 pm 12:18 PM

Table des matières Solution 1 Solution 21. Supprimez les fichiers temporaires de Windows Update 2. Réparez les fichiers système endommagés 3. Afficher et modifier les entrées de registre 4. Éteignez la carte réseau IPv6 5. Exécutez l'outil WindowsUpdateTroubleshooter pour réparer 6. Éteignez le pare-feu et autres logiciels antivirus associés. 7. Fermez le service WidowsUpdate. Solution 3 Solution 4 Une erreur « 0x8024401c » se produit lors de la mise à jour de Windows sur les ordinateurs Huawei Symptôme Problème Cause Solution Toujours pas résolu ? Récemment, le serveur Web a dû être mis à jour en raison de vulnérabilités du système. Après la connexion au serveur, la mise à jour affiche le code d'erreur 0x8024401c.

Exceptions de fonctions C++ et multithreading : gestion des erreurs dans les environnements concurrents Exceptions de fonctions C++ et multithreading : gestion des erreurs dans les environnements concurrents May 04, 2024 pm 04:42 PM

La gestion des exceptions de fonction en C++ est particulièrement importante pour les environnements multithread afin de garantir la sécurité des threads et l’intégrité des données. L'instruction try-catch vous permet d'intercepter et de gérer des types spécifiques d'exceptions lorsqu'elles se produisent afin d'éviter les plantages du programme ou la corruption des données.

Quelle est la relation entre les appels récursifs et la gestion des exceptions dans les fonctions Java ? Quelle est la relation entre les appels récursifs et la gestion des exceptions dans les fonctions Java ? May 03, 2024 pm 06:12 PM

Gestion des exceptions dans les appels récursifs : Limitation de la profondeur de récursion : Empêcher le débordement de pile. Utiliser la gestion des exceptions : utilisez les instructions try-catch pour gérer les exceptions. Optimisation de la récursivité de queue : évitez le débordement de pile.

Comment la gestion des exceptions C++ prend-elle en charge les routines de gestion des erreurs personnalisées ? Comment la gestion des exceptions C++ prend-elle en charge les routines de gestion des erreurs personnalisées ? Jun 05, 2024 pm 12:13 PM

La gestion des exceptions C++ permet la création de routines de gestion des erreurs personnalisées pour gérer les erreurs d'exécution en lançant des exceptions et en les interceptant à l'aide de blocs try-catch. 1. Créez une classe d'exception personnalisée dérivée de la classe d'exception et remplacez la méthode what() ; 2. Utilisez le mot-clé throw pour lancer une exception ; 3. Utilisez le bloc try-catch pour intercepter les exceptions et spécifier les types d'exception qui peuvent être générés. manipulé.

Comment gérer les exceptions dans les expressions C++ Lambda ? Comment gérer les exceptions dans les expressions C++ Lambda ? Jun 03, 2024 pm 03:01 PM

La gestion des exceptions dans les expressions C++ Lambda n'a pas sa propre portée et les exceptions ne sont pas interceptées par défaut. Pour intercepter les exceptions, vous pouvez utiliser la syntaxe de capture d'expression Lambda, qui permet à une expression Lambda de capturer une variable dans sa portée de définition, permettant ainsi la gestion des exceptions dans un bloc try-catch.

Gestion des exceptions en technologie C++ : Comment gérer correctement les exceptions dans un environnement multithread ? Gestion des exceptions en technologie C++ : Comment gérer correctement les exceptions dans un environnement multithread ? May 09, 2024 pm 12:36 PM

En C++ multithread, la gestion des exceptions suit les principes suivants : rapidité, sécurité des threads et clarté. En pratique, vous pouvez garantir la sécurité des threads du code de gestion des exceptions en utilisant des variables mutex ou atomiques. En outre, pensez à la réentrance, aux performances et aux tests de votre code de gestion des exceptions pour vous assurer qu'il s'exécute en toute sécurité et efficacement dans un environnement multithread.

Gestion des exceptions PHP : comprendre le comportement du système grâce au suivi des exceptions Gestion des exceptions PHP : comprendre le comportement du système grâce au suivi des exceptions Jun 05, 2024 pm 07:57 PM

Gestion des exceptions PHP : comprendre le comportement du système grâce au suivi des exceptions. Les exceptions sont le mécanisme utilisé par PHP pour gérer les erreurs, et les exceptions sont gérées par des gestionnaires d'exceptions. La classe d'exception Exception représente les exceptions générales, tandis que la classe Throwable représente toutes les exceptions. Utilisez le mot-clé throw pour lancer des exceptions et utilisez les instructions try...catch pour définir les gestionnaires d'exceptions. Dans des cas pratiques, la gestion des exceptions est utilisée pour capturer et gérer DivisionByZeroError qui peut être générée par la fonction calculate() afin de garantir que l'application peut échouer correctement lorsqu'une erreur se produit.

Comment gérez-vous efficacement les exceptions en PHP (essayez, attrapez, enfin, jetez)? Comment gérez-vous efficacement les exceptions en PHP (essayez, attrapez, enfin, jetez)? Apr 05, 2025 am 12:03 AM

En PHP, la gestion des exceptions est réalisée grâce aux mots clés d'essai, de catch, enfin et de lancement. 1) Le bloc d'essai entoure le code qui peut lancer des exceptions; 2) Le bloc de capture gère les exceptions; 3) Enfin, Block garantit que le code est toujours exécuté; 4) Le lancer est utilisé pour lancer manuellement les exceptions. Ces mécanismes aident à améliorer la robustesse et la maintenabilité de votre code.

See all articles