web-dev-qa-db-fra.com

Comment surmonter une HTMLExit ScriptException?

J'ai un problème avec une ligne de code qui déclenche probablement une fonction js et une exception, comment puis-je résoudre ce problème?

box.setText(link.toString());
client.waitForBackgroundJavaScriptStartingBefore(10000);
box.dblClick(); //this line cause the exception

Exception in thread "main" ======= EXCEPTION START ========
EcmaError: lineNumber=[0] column=[0] lineSource=[function () {] name=[ReferenceError] sourceName=[onclick event for HtmlDivision[<div class="_119 stat_elem focus_target mtm mbl _5bsm _6dh _51z6" id="u_0_k" data-location="maincolumn" onclick="Bootloader.loadComponents(&quot;ComposerXControllerBootload&quot;, emptyFunction);">] in https://www.facebook.com/?_fb_noscript=1] message=[ReferenceError: "Bootloader" is not defined.]
com.gargoylesoftware.htmlunit.ScriptException: ReferenceError: "Bootloader" is not defined.
    at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine$HtmlUnitContextAction.run(JavaScriptEngine.Java:684)
    at net.sourceforge.htmlunit.corejs.javascript.Context.call(Context.Java:602)
    at net.sourceforge.htmlunit.corejs.javascript.ContextFactory.call(ContextFactory.Java:507)
    at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.callFunction(JavaScriptEngine.Java:616)
    at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.callFunction(JavaScriptEngine.Java:591)
    at com.gargoylesoftware.htmlunit.html.HtmlPage.executeJavaScriptFunctionIfPossible(HtmlPage.Java:985)
    at com.gargoylesoftware.htmlunit.javascript.Host.EventListenersContainer.executeEventHandler(EventListenersContainer.Java:210)
    at com.gargoylesoftware.htmlunit.javascript.Host.EventListenersContainer.executeBubblingListeners(EventListenersContainer.Java:230)
    at com.gargoylesoftware.htmlunit.javascript.Host.Node.fireEvent(Node.Java:804)
    at com.gargoylesoftware.htmlunit.javascript.Host.Node.fireEvent(Node.Java:738)
    at com.gargoylesoftware.htmlunit.html.HtmlElement$1.run(HtmlElement.Java:869)
    at net.sourceforge.htmlunit.corejs.javascript.Context.call(Context.Java:602)
    at net.sourceforge.htmlunit.corejs.javascript.ContextFactory.call(ContextFactory.Java:507)
    at com.gargoylesoftware.htmlunit.html.HtmlElement.fireEvent(HtmlElement.Java:874)
    at com.gargoylesoftware.htmlunit.html.HtmlElement.doClickFireClickEvent(HtmlElement.Java:1311)
    at com.gargoylesoftware.htmlunit.html.HtmlElement.click(HtmlElement.Java:1253)
    at com.gargoylesoftware.htmlunit.html.HtmlElement.click(HtmlElement.Java:1205)
    at com.gargoylesoftware.htmlunit.html.HtmlElement.dblClick(HtmlElement.Java:1351)
    at com.gargoylesoftware.htmlunit.html.HtmlElement.dblClick(HtmlElement.Java:1326)
    at prototype.Profile.postLinkOnWall(Profile.Java:225)
    at html.Log.findNext(Log.Java:150)
    at prototype.Prtp.main(Prtp.Java:49)
Caused by: net.sourceforge.htmlunit.corejs.javascript.EcmaError: ReferenceError: "Bootloader" is not defined.
    at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.constructError(ScriptRuntime.Java:3603)
    at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.constructError(ScriptRuntime.Java:3587)
    at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.notFoundError(ScriptRuntime.Java:3657)
    at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.nameOrFunction(ScriptRuntime.Java:1749)
    at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.name(ScriptRuntime.Java:1690)
    at net.sourceforge.htmlunit.corejs.javascript.Interpreter.interpretLoop(Interpreter.Java:1622)
    at net.sourceforge.htmlunit.corejs.javascript.Interpreter.interpret(Interpreter.Java:798)
    at net.sourceforge.htmlunit.corejs.javascript.InterpretedFunction.call(InterpretedFunction.Java:105)
    at net.sourceforge.htmlunit.corejs.javascript.ContextFactory.doTopCall(ContextFactory.Java:405)
    at com.gargoylesoftware.htmlunit.javascript.HtmlUnitContextFactory.doTopCall(HtmlUnitContextFactory.Java:309)
    at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.doTopCall(ScriptRuntime.Java:3031)
    at net.sourceforge.htmlunit.corejs.javascript.InterpretedFunction.call(InterpretedFunction.Java:103)
    at com.gargoylesoftware.htmlunit.javascript.Host.EventHandler.call(EventHandler.Java:81)
    at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine$4.doRun(JavaScriptEngine.Java:609)
    at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine$HtmlUnitContextAction.run(JavaScriptEngine.Java:669)
    ... 21 more
Enclosed exception: 
net.sourceforge.htmlunit.corejs.javascript.EcmaError: ReferenceError: "Bootloader" is not defined.
    at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.constructError(ScriptRuntime.Java:3603)
    at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.constructError(ScriptRuntime.Java:3587)
    at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.notFoundError(ScriptRuntime.Java:3657)
    at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.nameOrFunction(ScriptRuntime.Java:1749)
    at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.name(ScriptRuntime.Java:1690)
    at net.sourceforge.htmlunit.corejs.javascript.Interpreter.interpretLoop(Interpreter.Java:1622)
    at script.onclick(onclick event for HtmlDivision[<div class="_119 stat_elem focus_target mtm mbl _5bsm _6dh _51z6" id="u_0_k" data-location="maincolumn" onclick="Bootloader.loadComponents(&quot;ComposerXControllerBootload&quot;, emptyFunction);">] in https://www.facebook.com/?_fb_noscript=1)
    at net.sourceforge.htmlunit.corejs.javascript.Interpreter.interpret(Interpreter.Java:798)
    at net.sourceforge.htmlunit.corejs.javascript.InterpretedFunction.call(InterpretedFunction.Java:105)
    at net.sourceforge.htmlunit.corejs.javascript.ContextFactory.doTopCall(ContextFactory.Java:405)
    at com.gargoylesoftware.htmlunit.javascript.HtmlUnitContextFactory.doTopCall(HtmlUnitContextFactory.Java:309)
    at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.doTopCall(ScriptRuntime.Java:3031)
    at net.sourceforge.htmlunit.corejs.javascript.InterpretedFunction.call(InterpretedFunction.Java:103)
    at com.gargoylesoftware.htmlunit.javascript.Host.EventHandler.call(EventHandler.Java:81)
    at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine$4.doRun(JavaScriptEngine.Java:609)
    at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine$HtmlUnitContextAction.run(JavaScriptEngine.Java:669)
    at net.sourceforge.htmlunit.corejs.javascript.Context.call(Context.Java:602)
    at net.sourceforge.htmlunit.corejs.javascript.ContextFactory.call(ContextFactory.Java:507)
    at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.callFunction(JavaScriptEngine.Java:616)
    at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.callFunction(JavaScriptEngine.Java:591)
    at com.gargoylesoftware.htmlunit.html.HtmlPage.executeJavaScriptFunctionIfPossible(HtmlPage.Java:985)
    at com.gargoylesoftware.htmlunit.javascript.Host.EventListenersContainer.executeEventHandler(EventListenersContainer.Java:210)
    at com.gargoylesoftware.htmlunit.javascript.Host.EventListenersContainer.executeBubblingListeners(EventListenersContainer.Java:230)
    at com.gargoylesoftware.htmlunit.javascript.Host.Node.fireEvent(Node.Java:804)
    at com.gargoylesoftware.htmlunit.javascript.Host.Node.fireEvent(Node.Java:738)
    at com.gargoylesoftware.htmlunit.html.HtmlElement$1.run(HtmlElement.Java:869)
    at net.sourceforge.htmlunit.corejs.javascript.Context.call(Context.Java:602)
    at net.sourceforge.htmlunit.corejs.javascript.ContextFactory.call(ContextFactory.Java:507)
    at com.gargoylesoftware.htmlunit.html.HtmlElement.fireEvent(HtmlElement.Java:874)
    at com.gargoylesoftware.htmlunit.html.HtmlElement.doClickFireClickEvent(HtmlElement.Java:1311)
    at com.gargoylesoftware.htmlunit.html.HtmlElement.click(HtmlElement.Java:1253)
    at com.gargoylesoftware.htmlunit.html.HtmlElement.click(HtmlElement.Java:1205)
    at com.gargoylesoftware.htmlunit.html.HtmlElement.dblClick(HtmlElement.Java:1351)
    at com.gargoylesoftware.htmlunit.html.HtmlElement.dblClick(HtmlElement.Java:1326)
    at prototype.Profile.postLinkOnWall(Profile.Java:225)
    at html.Log.findNext(Log.Java:150)
    at prototype.Prtp.main(Prtp.Java:49)
== CALLING JAVASCRIPT ==
function () {
    [native code, arity=0]
}

======= EXCEPTION END ========

La boîte où j'écris agit sur un navigateur normal d'une fonction de reformatage qui n'est pas effectuée à l'aide de HtmlUnit, j'ai donc essayé de le forcer avec un dbclick ().

20
user3054975

HtmlUnit ne fonctionne pas bien avec JavaScript. Il y aura souvent des erreurs en se plaignant de variables ou de fonctions non définies.

En ce sens, les navigateurs real life (FireFox, Internet Explorer, Chrome, etc.) sont beaucoup plus flexibles. Cela signifie qu'ils autoriseront des éléments HTML et JavaScript incorrects du point de vue de la syntaxe (par exemple: ne pas définir de fonctions ou ne pas terminer les balises HTML).

HtmlUnit s'attend à ce que tout soit (presque) parfait. Bien que cela corrige certaines balises HTML finales manquantes, en général, il s'attend à ce que le code dans les pages ne contienne aucun type d'erreur. De plus, même si tout semble correct, HtmlUnit pourrait même se plaindre.

Certains éléments auxquels vous devez penser sont:

  • Le plus important est de basculer entre différents BrowserVersions. Vous pouvez les définir lors de la création de l'objet WebClient. Internet Explorer (ironiquement) s’est avéré donner les meilleurs résultats en matière d’interprétation de JavaScript
  • Assurez-vous que votre code HTML et JavaScript sont corrects
  • Évitez d'utiliser des bibliothèques complex (jQuery semble être correctement pris en charge)
  • Essayez d'utiliser des versions non minimisées des bibliothèques
  • Si vous utilisez jQuery (ou d’autres bibliothèques similaires), évitez les méthodes complexes de jQuery (par exemple, l’ajout dynamique d’événements à des éléments).

Bien entendu, ces commentaires s’appliqueraient si vous contrôliez le code source que vous extrayez du serveur. Parfois, ce n'est pas le cas. Dans cette situation, vos mains sont encore plus liées.

Une option serait de supprimer l'exception avec:

webClient.getOptions().setThrowExceptionOnScriptError(false);

Bien que cela vous permette de passer à travers l'exception, aucune erreur JavaScript ne sera corrigée. Cela signifie que si le morceau de code JS qui lève cette exception s'avère crucial dans votre logique, je veux dire, vous dépendez absolument du résultat de l'exécution de ce code, vous ne pouvez pas laisser HtmlUnit gérer votre JS. Si cela résulte d'une requête AJAX, vous pouvez alors émettre la demande vous-même manuellement au lieu de laisser HtmlUnit le faire.

D'un autre côté, si le code JS qui vous cause des problèmes n'est pas critique dans votre logique, vous pouvez peut-être simplement cacher un élément ou changer une couleur qui ne vous intéresse pas, puis supprimer l'exception serait la marche à suivre.

Il ne reste plus beaucoup d'options.

32
Mosty Mostacho

Essayez de configurer votre client Web pour ne pas lancer d'exception:

client.getOptions().setThrowExceptionOnScriptError(false);
8
Gokul Nath KP

J'ai eu le même problème quand j'ai un site avec la méthode:

webClient.getPage("http://somepage.com");

Si vous n'avez pas besoin d'utiliser JavaScript pour travailler avec des sites Web, vous pouvez écrire:

webClient.getOptions().setJavaScriptEnabled(false);

Dans mon cas, cela fonctionne bien et le script fonctionne immédiatement (quand j’utilisais seulement webClient.getOptions().setThrowExceptionOnScriptError(false), le script essayait toujours d’exécuter du code JavaScript incorrect et pendant environ 10 secondes, écrivant des messages d’exception dans la console, je déconseille donc de l’utiliser).

0
Oxygenium