web-dev-qa-db-fra.com

Runtime.lastError décoché lors de l'utilisation de l'API Chrome

J'utilise l'API chrome.fileSystem dans mon application pour ouvrir un fichier. Lorsque je clique sur le bouton Cancel de la boîte de dialogue du sélecteur de fichier, une erreur se produit:

Désactivé runtime.lastError pendant l'exécution de fileSystem.chooseEntry: utilisateur annulé

Comment réparer cette erreur?

17
zcfrank1st

Cette erreur n'est pas importante dans ce cas, mais je vais l'expliquer et comment s'en débarrasser.

Quelle est cette erreur?

Les API Chrome sont généralement asynchrones: vous avez un rappel appelé à la fin de l'opération.

Dans le cas de chrome.fileSystem.chooseEntry, la ou les entrées choisies seront transmises à un rappel:

chrome.fileSystem.chooseEntry(
  {/* options */},
  function(entry) {
    // This is the callback for the API call; you can do something with entry
  }
);

Cependant, il n'est pas garanti que l'API donne un résultat. Par exemple, comme dans votre cas, l'utilisateur peut refuser de fournir l'accès en cliquant sur "Annuler". Ensuite, il n'y a pas d'entrée dans laquelle travailler, et vous voudrez peut-être une explication de la raison pour laquelle cela s'est produit. Comment générer une erreur sans polluer tous les rappels avec un argument supplémentaire "erreur"?

En règle générale, Chrome règle ce problème en définissant une variable globale, chrome.runtime.lastError, au moment de l'appel du rappel. Il est uniforme dans les API asynchrones de Chrome d'utiliser cet argument au lieu d'un argument d'erreur. En fait, citant les docs chrome.fileSystem:

Tous les échecs sont notifiés via chrome.runtime.lastError. 

  • Si tout va bien, ce sera undefined.
  • S'il y a un problème, il sera non vide et chrome.runtime.lastError.message expliquera ce qui ne va pas.

Cependant, certains callbacks n'ont pas vérifié cette variable d'erreur. Cela peut indiquer une erreur de programmation, et Chrome ajouté vérifie que chrome.runtime.lastError est réellement vérifié (évalué) dans un rappel. Sinon, il considère qu'il s'agit d'une exception non gérée et lève cette erreur.

Pourquoi je dis que ce n'est pas important?

Même s’il s’agit d’une erreur, l’exécution de votre programme n’est pas interrompue (elle est renvoyée à la fin d’une tâche asynchrone) et ne s'affiche pas vraiment pour vos utilisateurs.

Et même si je dis que ce n'est pas important, vous devriez vérifier la logique de votre programme. Cela peut être ou ne pas être correct - ceci est censé être un avertissement (sévère).

Pourquoi existe-t-il?

Pour avertir vous, le développeur, que votre code probablement tente d'utiliser un résultat inexistant, car une erreur s'est produite.

Il est possible que vous recherchiez déjà une erreur, par exemple.

if (entry) {
  // Process entry
} else {
  // Something went wrong (but what?)
}

Chrome n'utilise pas d'heuristique complexe pour voir si votre code s'attend à cette possibilité. Comme indiqué, les erreurs sont signalées via chrome.runtime.lastError et vous êtes invité à les vérifier.

Notez que cette erreur est uniquement générée lorsque quelque chose de grave ne se produit, et non lorsque l'appel de l'API se termine normalement.

Puis-je l'attraper?

Pas vraiment; cela ne provient pas de votre code, mais du code de nettoyage qui gère les tâches asynchrones dans l'API Chrome; Par conséquent, utiliser try ... catch dans votre rappel ne vous aidera pas. Comme c'est asynchrone, utiliser try autour de l'appel d'API d'origine ne sera d'aucun secours.

Que dois-je faire avec ça?

Vous devez ajouter à votre rappel une logique qui vérifie la présence de problèmes, comme prévu par Chrome, et y réagit probablement.

function(entry) {
  if(chrome.runtime.lastError) {
    // Something went wrong
    console.warn("Whoops.. " + chrome.runtime.lastError.message);
    // Maybe explain that to the user too?
  } else {
    // No errors, you can use entry
  }
}

Tant que Chrome verra que vous avez coché la valeur en cas d'erreur (c'est-à-dire qu'elle a été évaluée dans votre rappel), l'erreur ne sera pas renvoyée.

43
Xan

En retard pour la fête, mais voici comment j'ai supprimé l'erreur dans un appel chrome.windows.remove(), au cas où cela aiderait quelqu'un d'autre. Au lieu de

chrome.windows.remove(foo);  // unconditional; runtime.lastError not checked

J'ai utilisé

chrome.windows.remove(
        foo,
        function ignore_error() { void chrome.runtime.lastError; }
);

void évalue son opérande puis renvoie undefined. Je pense que ce code documente assez efficacement que son but est d'ignorer les erreurs :).

Par souci de brièveté, ignore_error() pourrait être extrait de cet appel et utilisé pour plusieurs appels d'API chrome ou le nom ignore_error pourrait être omis.

Update Dans ES6, vous pouvez utiliser la syntaxe plus courte fonction de flèche

chrome.windows.remove( foo, ()=>void chrome.runtime.lastError );

Testé sous Chrome 64

2
cxw

Pour ce type d'erreur, try catch ne sera pas utile. Au lieu de cela, vous pouvez accéder à la variable globale chrome.runtime.lastError en tant que @xan mentionné dans sa réponse ci-dessus (par la façon dont vous devriez la lire et la faire passer à la hausse!).

Maintenant, voici un exemple qui peut être utilisé:

function catchLastError(){
  if(chrome.runtime.lastError){
    console.log("error: ", chrome.runtime.lastError);
  }else{
    // some code goes here.
  }
}

chrome.fileSystem.chooseEntry(yourEntry,catchLastError);
0
ismnoiet