flex exception error-handling

Cómo atrapar todas las excepciones en Flex?



exception error-handling (9)

Cuando ejecuto una aplicación Flex en el reproductor de depuración, recibo una excepción emergente tan pronto como ocurre algo inesperado. Sin embargo, cuando un cliente utiliza la aplicación, no utiliza el reproductor flash de depuración. En este caso, no obtiene una excepción emergente, pero la interfaz de usuario no funciona.

Por razones de compatibilidad, me gustaría detectar cualquier excepción que pueda ocurrir en cualquier lugar de la interfaz de usuario de Flex y presentar un mensaje de error en una ventana emergente interna de Flex. Al usar Java, simplemente encapsularía todo el código de UI en un bloque de prueba / captura, pero con aplicaciones MXML en Flex no sé dónde podría realizar una prueba / captura tan general.


Adjunté el oyente del evento a la ''raíz'', que funcionó para mí:

sprite.root.loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, onUncaughtError);

En la depuración de Flash Player, esto seguirá generando un error, pero en la versión sin depuración el error aparecerá en el cuadro de diálogo de Flash Player, y luego el controlador responderá. Para evitar que aparezca el cuadro de diálogo, agregue:

event.preventDefault();

asi que:

private function onUncaughtError(event:UncaughtErrorEvent):void { event.preventDefault(); // do something with this error }

Estaba usando esto en AIR, pero supongo que también funciona para proyectos estándar de AS3.



Alternativa a la respuesta aceptada, utilizando try-catch. Más lento, pero más fácil de leer, creo.

try { loaderInfo.uncaughtErrorEvents.addEventListener("uncaughtError", onUncaughtError); } catch (e:ReferenceError) { var spl:Array = Capabilities.version.split(" "); var verSpl:Array = spl[1].split(","); if (int(verSpl[0]) >= 10 && int(verSpl[1]) >= 1) { // This version is 10.1 or greater - we should have been able to listen for uncaught errors... d.warn("Unable to listen for uncaught error events, despite flash version: " + Capabilities.version); } }

Por supuesto, deberá usar un 10.1 playerglobal.swc actualizado para compilar este código con éxito: http://labs.adobe.com/downloads/flashplayer10.html


Estoy usando flex 4. Intenté loaderInfo.UncaughtErrorEvents, pero loaderInfo no se inicializó, por lo que me dio un error de referencia nulo. Entonces probé root.loaderInfo.UncaughtErrorEvents y la misma historia. Intenté sprite.root.UncaughtErrorEvents , pero no había objeto sprite, creé uno, pero no funcionó. Finalmente probé

systemManager.loaderInfo.uncaughtErrorEvents.addEventListener (UncaughtErrorEvent.UNCAUGHT_ERROR, globalUnCaughtErrorHandler.hanleUnCaughtError);

Y adivina qué, funciona como magia. mira this


Funciona en Flex 3.3.

if(loaderInfo.hasOwnProperty("uncaughtErrorEvents")){ IEventDispatcher(loaderInfo["uncaughtErrorEvents"]).addEventListener("uncaughtError", uncaughtErrorHandler); }


Funciona en Flex 3.5 y flash player 10:

<?xml version="1.0" encoding="utf-8"?>

protected function application1_addedToStageHandler(event:Event):void{ if(loaderInfo.hasOwnProperty("uncaughtErrorEvents")){ IEventDispatcher(loaderInfo["uncaughtErrorEvents"]).addEventListener("uncaughtError", uncaughtErrorHandler); } sdk.text = "Flex " + mx_internal::VERSION; } private function uncaughtErrorHandler(e:*):void{ e.preventDefault(); var s:String; if (e.error is Error) { var error:Error = e.error as Error; s = "Uncaught Error: " + error.errorID + ", " + error.name + ", " + error.message; } else { var errorEvent:ErrorEvent = e.error as ErrorEvent; s = "Uncaught ErrorEvent: " + errorEvent.text; } msg.text = s; } private function unCaught():void { var foo:String = null; trace(foo.length); } ]]> </mx:Script> <mx:VBox> <mx:Label id="sdk" fontSize="18"/> <mx:Button y="50" label="UnCaught Error" click="unCaught();" /> <mx:TextArea id="msg" width="180" height="70"/> </mx:VBox>

Gracias



No hay forma de recibir notificaciones sobre excepciones no detectadas en Flex 3. Adobe conoce el problema, pero no sé si planea crear una solución alternativa.

La única solución tal como está es poner try / catch en lugares lógicos y asegurarse de que está escuchando el evento ERROR (o FAULT for webservices) para cualquier cosa que los despache.

Editar: Además, es realmente imposible detectar un error lanzado desde un manejador de eventos. He registrado un bug en el sistema Adobe Bug.

Actualización 2010-01-12: el manejo de errores globales ahora es compatible con Flash 10.1 y AIR 2.0 (ambos en versión beta), y se logra suscribiendo el evento LoaderInfo.uncaughtErrorEvents de LoaderInfo.uncaughtErrorEvents . El siguiente código se toma del LoaderInfo.uncaughtErrorEvents :

public class UncaughtErrorEventExample extends Sprite { public function UncaughtErrorEventExample() { loaderInfo.uncaughtErrorEvents.addEventListener( UncaughtErrorEvent.UNCAUGHT_ERROR, uncaughtErrorHandler); } private function uncaughtErrorHandler(event:UncaughtErrorEvent):void { if (event.error is Error) { var error:Error = event.error as Error; // do something with the error } else if (event.error is ErrorEvent) { var errorEvent:ErrorEvent = event.error as ErrorEvent; // do something with the error } else { // a non-Error, non-ErrorEvent type was thrown and uncaught } }