En JS, il ne semble pas possible de vérifier si un argument transmis à une fonction est en réalité du type "erreur" ou une instance de Erreur.
Par exemple, ceci n'est pas valide:
typeof err === 'error'
puisqu'il n'y a que 6 types possibles (sous forme de chaînes):
L'opérateur typeof renvoie les informations de type sous forme de chaîne. typeof
renvoie six valeurs possibles:
"nombre", "chaîne", "booléen", "objet", "fonction" et "indéfini".
Mais que se passe-t-il si j'ai un cas d'utilisation simple comme celui-ci:
function errorHandler(err) {
if (typeof err === 'error') {
throw err;
}
else {
console.error('Unexpectedly, no error was passed to error handler. But here is the message:',err);
}
}
alors quel est le meilleur moyen de déterminer si un argument est une instance de Error?
l’opérateur instanceof
at-il de l’aide?
Vous pouvez utiliser l'opérateur instanceof
.
var myError = new Error('foo');
myError instanceof Error // true
var myString = "Whatever";
myString instanceof Error // false
J'ai posé la question initiale - la réponse de @Trott est sûrement la meilleure.
Cependant, JS étant un langage dynamique et le nombre d'environnements d'exécution JS étant très nombreux, l'opérateur instanceof
peut échouer, en particulier dans le développement front-end lors du franchissement de limites telles que les iframes. Voir: https://github.com/mrdoob/three.js/issues/5886
Si vous êtes d'accord avec la frappe de canard, cela devrait être bon:
let isError = function(e){
return e && e.stack && e.message;
}
Personnellement, je préfère les langages à typage statique, mais si vous utilisez un langage dynamique, il vaut mieux adopter un langage dynamique pour ce qu’il est, plutôt que de le forcer à se comporter comme un langage à typage statique.
si vous voulez être un peu plus précis, vous pouvez le faire:
let isError = function(e){
return e && e.stack && e.message && typeof e.stack === 'string'
&& typeof e.message === 'string';
}
var myError = new Error('foo');
myError instanceof Error // true
var myString = "Whatever";
myString instanceof Error // false
Le seul problème avec ceci est
myError instanceof Object // true
Une alternative à cela serait d'utiliser la propriété constructeur.
myError.constructor === Object // false
myError.constructor === String // false
myError.constructor === Boolean // false
myError.constructor === Symbol // false
myError.constructor === Function // false
myError.constructor === Error // true
Bien qu'il faille noter que cette correspondance est très spécifique, par exemple:
myError.constructor === TypeError // false
Vous pouvez utiliser obj.constructor.name pour vérifier la "classe" d'un objet https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name#Function_names_in_classes
Par exemple
var error = new Error("ValidationError");
console.log(error.constructor.name);
La ligne ci-dessus consignera "Erreur", qui correspond au nom de classe de l'objet. Cela peut être utilisé avec toutes les classes en javascript, si la classe n'utilise pas une propriété nommée "name"
Ou utilisez ceci pour différents types d'erreurs
function isError(val) {
return (!!val && typeof val === 'object')
&& ((Object.prototype.toString.call(val) === '[object Error]')
|| (typeof val.message === 'string' && typeof val.name === 'string'))
}