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 defileSystem.chooseEntry
: utilisateur annulé
Comment réparer cette erreur?
Cette erreur n'est pas importante dans ce cas, mais je vais l'expliquer et comment s'en débarrasser.
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.
undefined
.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.
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).
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.
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.
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.
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
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);