Aspnetcore: Manejo de excepciones globales

Creado en 26 ago. 2019  ·  51Comentarios  ·  Fuente: dotnet/aspnetcore

Hola chicos, quería saber cuál es la mejor manera de capturar una excepción a nivel de la aplicación, para evitar poner try catch en todos mis métodos y componentes, y centralizar la gestión de excepciones en un punto (generalmente muestra una notificación de error y registra la excepción) .

Entonces, ¿hay una mejor manera de hacer esto en la vista previa8, o algo planeado para el RTM?

Gracias !

Components Big Rock affected-most area-blazor enhancement severity-major

Comentario más útil

¿Alguna actualización sobre este tema?

Actualmente, mi aplicación blazor del lado del servidor simplemente dejó de responder a la entrada del usuario después de que se lanzó una excepción.

No es una buena práctica cubrir todas las líneas de código con try-catch (ni esperar que el desarrollador lo haga), en caso de una excepción "no prevista", deberíamos tener un controlador genérico que nos permita:

1. Elija si desea interrumpir el circuito.
2.Muéstrele a nuestro usuario un mensaje GUI "amigable" o simplemente rediríjalo a una página de error genérica.

Actualmente, después de una excepción no manejada, la aplicación no puede notificar al usuario sobre un problema y el usuario solo puede volver a ejecutar la aplicación (cerrar el navegador e ir a la URL de la aplicación nuevamente) o actualizar la página y perder todo el estado (que a veces es bueno, pero el desarrollador de la aplicación debe elegir esto).

Todos 51 comentarios

Todas las excepciones no controladas deberían terminar en el registrador. Si ve lo contrario, háganoslo saber y estaremos encantados de investigar. Mirar los registros debería ser el camino a seguir aquí.

Bien, lo que entiendo es que tengo que proporcionar mi propia implementación de ILogger. y está en mi implementación, ¿tengo que lidiar con la excepción? (por ejemplo, muestre una notificación, escriba una excepción en un archivo para el lado del servidor y envíelo al controlador para el lado del cliente)
en realidad, lo único que se encuentra es este paquete https://github.com/BlazorExtensions/Logging
Realmente no entiendo cómo usarlo, parece que solo podemos iniciar sesión en la consola con esto.

Pero incluso con esta extensión, si hay una excepción no controlada en el código, la aplicación falla.

Entonces, si entiendo, no tengo la opción de rodear todo mi código con try catch.

Gracias por tu explicación

Cualquiera de los proveedores de registradores enumerados aquí: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-2.2#built-in-logging-providers como también proveedores desarrollados por la comunidad ( https://github.com/aspnet/Extensions/tree/master/src/Logging#providers) debería funcionar.

Pero incluso con esta extensión, si hay una excepción no controlada en el código, la aplicación falla.

Para Blazor del lado del servidor, una excepción no controlada debería desconectar el circuito, pero no bloquear la aplicación. Si un bloque está destinado a lanzar una excepción que puede tolerar, un try-catch parece ser la forma más razonable de proceder. ¿Qué planea hacer con las excepciones no controladas si detecta una excepción arbitraria?

Blazor del lado del cliente no registra ninguna excepción. Solo se imprimen en la consola. Aquí está el código de WebAssemblyRenderer

protected override void HandleException(Exception exception)
{
    Console.Error.WriteLine($"Unhandled exception rendering component:");
    if (exception is AggregateException aggregateException)
    {
        foreach (var innerException in aggregateException.Flatten().InnerExceptions)
        {
            Console.Error.WriteLine(innerException);
        }
    }
    else
    {
        Console.Error.WriteLine(exception);
    }
}

La única forma que encontré que puede interceptar excepciones se describe aquí
https://remibou.github.io/Excepciones-manejo-en-Blazor/

Pero yo no llamaría a esto manejo de excepciones...

Me gustaría tener un controlador de excepciones global para poder escribir mi código sin bloques catch...

{
   IsLoading = true;
   await SomeAsync();
}
finally
{
   IsLoading = false;
   //force rerender after exception
    StateHasChanged();
}

Si el método SomeAsync arroja una excepción, mi varialbe IsLoading se establece en falso, pero mi vista no se vuelve a representar. Tienes que llamar a SetStateHasChanged en bloque final para forzar la visualización

para el blazor del lado del cliente, finalmente escribo mi propia implementación en ILogger (inspirado en el código de implementación predeterminado que inicia sesión en la consola).
Con esta implementación, puedo llamar a un LoggerController en mi servidor, que también se inyecta un ILogger (pero esta vez, es una implementación de NLog que se inyecta, por lo que puedo escribir correctamente todas las excepciones en el servidor)

Abandono la idea del manejo global de excepciones, que parece no ser la lógica de blazor, y pongo try/catch en todas partes e inyecto un ILoggeren todo componente.

Excepto si cree que hay algo mejor que hacer, puede cerrar este problema.

Creo que esta es una característica que falta. Cuando se lanza una excepción, también me gustaría tener un lugar centralizado para capturar todas las excepciones no controladas y hacer algo. Mostrarlo en una ventana emergente, registrarlo en algún lugar, enviarlo al servidor o lo que sea. .. sin ningún daño al estado de la aplicación
Algo así como el evento UnhandledException en WPF
https://docs.microsoft.com/en-us/dotnet/api/system.appdomain.unhandledexception?redirectedfrom=MSDN&view=netframework-4.8

¿No es el ILogger ya ese lugar centralizado?

@SteveSandersonMS mira mi comentario anterior
https://github.com/aspnet/AspNetCore/issues/13452#issuecomment-535227410
Las excepciones (en el lado del cliente blazor) se escriben en la consola usando Console.Error.WriteLine, no se registran usando ILogger. Podría implementar un TextWriter personalizado y reemplazar Console.Error
https://remibou.github.io/Excepciones-manejo-en-Blazor/
pero obtiene una representación de cadena de una excepción. Analizar esa cadena, que incluye un seguimiento de pila, e intentar obtener (por ejemplo) solo un mensaje de excepción es engorroso por decir lo menos.
Me gustaría obtener acceso al objeto de excepción para poder hacer mi propio registro (o lo que sea)

@rborosak ¡ Gracias por la aclaración!

¿Alguna actualización sobre este tema?

Actualmente, mi aplicación blazor del lado del servidor simplemente dejó de responder a la entrada del usuario después de que se lanzó una excepción.

No es una buena práctica cubrir todas las líneas de código con try-catch (ni esperar que el desarrollador lo haga), en caso de una excepción "no prevista", deberíamos tener un controlador genérico que nos permita:

1. Elija si desea interrumpir el circuito.
2.Muéstrele a nuestro usuario un mensaje GUI "amigable" o simplemente rediríjalo a una página de error genérica.

Actualmente, después de una excepción no manejada, la aplicación no puede notificar al usuario sobre un problema y el usuario solo puede volver a ejecutar la aplicación (cerrar el navegador e ir a la URL de la aplicación nuevamente) o actualizar la página y perder todo el estado (que a veces es bueno, pero el desarrollador de la aplicación debe elegir esto).

@hagaygo ¡ Muy buen resumen!

@SteveSandersonMS ¡ Considere esto para el hito 3.1.x! Por favor, no mueva esto a 5.0.0

Hola,

Recibo este tipo de error cuando el circuito se rompe en la consola de la ventana del desarrollador.

image

No creo que de todos modos actualmente pueda notificar al usuario que se ha producido un error después de esto en la pantalla y solicitar que se actualice sin abrir manualmente la ventana del desarrollador para verificar y actualizar la página.

@SteveSandersonMS ¿Podría aclarar si app.UseExceptionHandler() funciona o no para blazor del lado del servidor?

He visto varios casos en los que mi ErrorHandler personalizado no detecta las excepciones que lanza mi aplicación. Código de ejemplo

Startup.cs :

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IServiceProvider serviceProvider)
{
    ...
    app.UseExceptionHandler(new ExceptionHandlerOptions { ExceptionHandler = ErrorHandler.HandleError });
    ...
}

ErrorHandler.cs :

public static async Task HandleError(HttpContext context)
{
    var error = context.Features.Get<IExceptionHandlerFeature>()?.Error;
    var message = error?.Message ?? "[EXCEPTION NOT FOUND]";        
    return;
}

Un ejemplo es cuando mi repositorio lanza una excepción como tal:
The instance of entity type cannot be tracked because another instance with the same key value for {'Id'} is already being tracked

Mi solución MVC está detectando todas las excepciones y está utilizando implementaciones similares de Manejo de errores.

Mover esto a la versión 5.0 para destilar las solicitudes específicas aquí y ver si podemos abordar algunas de ellas.

el mayor problema para mí son los límites de error . Quiero poder usar un componente de terceros y, de alguna manera, envolver mi uso de ese componente en el manejo de errores para que un error en la biblioteca no elimine toda mi aplicación web. en este momento no hay un "lugar para colocar el botón de prueba": todo el árbol de componentes está supervisado por el renderizador blazor, que morirá si algo en lo profundo del árbol se estropea.

+1 para esta función.
Tener que poner el bloque try/catch en todos los métodos no es una forma razonable de hacerlo.

Personalmente, solía lanzar una excepción para administrar los errores comerciales. En un nivel alto, capturo la excepción y de acuerdo a su tipo, decido si la excepción debe registrarse, mostrarse al usuario y mostrarse si muestro el mensaje completo (excepciones comerciales) o simplemente un "Algo sale mal") .

En realidad, la única forma que encontré para hacer algo como esto es crear una clase ComponentBaseEx que herede a ComponentBase y anule OnInitialized (Async), OnParametersSet (Async), ...
Desafortunadamente, incluso con este camino a seguir, tengo que administrar manualmente todas las acciones del usuario (eliminar un cliente, ...)

Tu crees
1) se puede hacer algo?
2) en caso afirmativo, ¿cuándo?

Este es mi escenario: aplicación de escritorio/híbrida Blazor que usa el servidor Blazor. Un usuario inició sesión a la vez y el estado persiste entre recargas. Por lo tanto, si hay una excepción no controlada, no hay forma de que la aplicación vuelva a un estado confiable que no sea reiniciarla. Necesitamos detectar excepciones no controladas, mostrar la experiencia de usuario adecuada y luego apagar. Patrón de aplicación de escritorio estándar.

Truco temporal: hemos configurado el registro con Serilog. Serilog tiene una API que le permite filtrar todos los mensajes de registro y decidir si se emiten. Abusamos de esta API comprobando si un evento de registro tiene una clave CircuitId en su diccionario de propiedades. Si es así, eso significa que un circuito ha muerto, es decir, hay una excepción no controlada. Podemos sacar la excepción infractora del objeto de mensaje de registro que examinamos. Presto: tiene en sus manos la excepción no controlada en la parte superior y puede hacer lo que quiera con ella.

Hola chicos, al igual que los demás, estoy realmente preocupado si mueven esto al hito de .NET 5.
Después de un año de trabajo en blazor reescribiendo una aplicación antigua de Silverlight, se supone que debo implementar mi aplicación en producción en mayo/junio (cuando webasssembly esté listo para la producción).

Pero definitivamente no puedo hacer eso sin una forma sólida de detectar o al menos registrar todos los errores inesperados.

Considere hacer algo, aunque no sea perfecto, antes de la versión 5.0 (solo un método con la excepción está bien para mí, al menos podemos iniciar sesión...)

¡Muchas gracias!

Hola estoy en la misma situacion que @julienGrd
Por favor haga algo para ayudarnos/guiarnos.
¡Saludos!

Lo mismo pasa conmigo.

Hemos utilizado el lado del servidor Blazor para todo nuestro desarrollo y migrado desde
las páginas web heredadas de ASP.Net.

El martes 3 de marzo de 2020 a las 12:02 eliudgerardo [email protected]
escribió:

Hola estoy en la misma situacion que @julienGrd
https://github.com/julienGrd
Por favor haga algo para ayudarnos/guiarnos.
¡Saludos!


Estás recibiendo esto porque comentaste.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/dotnet/aspnetcore/issues/13452?email_source=notifications&email_token=ANKYSDFSUQ3OTBGWQMRV5EDRFUZ27A5CNFSM4IPQWA62YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOENUJXLA46 , 05 comentario-59
o darse de baja
https://github.com/notifications/unsubscribe-auth/ANKYSDGFCDRMZV2N4NLMOMLRFUZ27ANCNFSM4IPQWA6Q
.

--
ankit bansal

*Juegos Científicos*

La intención es que pueda registrar todas las excepciones no detectadas utilizando la interfaz ILogger . Esto significa que puede conectar su propio sistema de registro personalizado que hace lo que quiera con la información de excepción.

Sin embargo , todavía hay una parte de esto que aún no hemos implementado. Esto está siendo rastreado por https://github.com/dotnet/aspnetcore/issues/19533. Nos aseguraremos de hacer esto pronto.

debería poder registrar todas las excepciones no detectadas utilizando la interfaz ILogger

@SteveSandersonMS Creo que lo que buscamos aquí es una API mucho más general, que simplemente le proporcione una excepción no detectada para hacer lo que queramos, con la excepción en sí misma. Imagine que queremos examinar la excepción y posiblemente reaccionar de alguna manera, tal vez enviar el excepción a un servicio de seguimiento de excepciones como Raygun, o presentar alguna interfaz de usuario basada en el contenido. Sin dicha API, debemos hacer un mal uso de la interfaz ILogger para lograr todas estas cosas, lo cual es incómodo. ¿Por qué no proporcionar esa API mucho más general, en lugar de forzar todos los escenarios posibles a través de una implementación de ILogger?

La intención es que pueda registrar todas las excepciones no detectadas utilizando la interfaz ILogger . Esto significa que puede conectar su propio sistema de registro personalizado que hace lo que quiera con la información de excepción.

@SteveSandersonMS Por casualidad, ¿tiene un ejemplo de referencia para hacer esto en una aplicación Server Side Blazor? Mi intención es después de registrar una excepción no detectada, mostrar un mensaje amistoso al usuario. La ayuda será apreciada. Saludos.

@eliudgerardo Blazor Server ya muestra una interfaz de usuario orientada al usuario cuando hay un error no controlado. Puede personalizar esta interfaz de usuario. Los documentos al respecto están en https://docs.microsoft.com/en-us/aspnet/core/blazor/handle-errors?view=aspnetcore-3.1#detailed-errors-uring-development

@SteveSandersonMS Soy consciente de la opción que menciona, pero me temo que, en ese caso, el circuito de conexión está roto y no quiero envolver todas mis llamadas API con try/catch. Entonces, ¿hay alguna manera de lograr eso?

@eliudgerardo ¿Por qué importa que el circuito esté roto? ¿Su objetivo es permitir que el usuario continúe usando el circuito incluso después de la excepción no controlada?

@SteveSandersonMS ¡No queremos que se rompa el circuito!. Si ocurre una excepción (en nuestra aplicación o en algún lugar de la biblioteca de terceros que estamos usando), nos gustaría un lugar donde pudiéramos mostrar un cuadro de diálogo que diga "Algo salió mal {excepción.Mensaje}" y la aplicación continuaría funcionando. Tenemos una solución parcial para esto, envolver los métodos del ciclo de vida y nuestros métodos en el bloque try catch, pero eso es engorroso y hay un problema con las bibliotecas de terceros...

@partyelite Si no se maneja una excepción, entonces ese circuito ahora está en un estado desconocido. Ya no podemos decir si los recursos dentro de él todavía se pueden usar, si su lógica de seguridad se ha ejecutado por completo o cualquier otra cosa. Si se sigue utilizando el circuito, eso podría crear un comportamiento indefinido, incluidos posibles problemas de seguridad, que son problemáticos dado que este código se está ejecutando en su servidor.

Una posibilidad que estamos considerando para el futuro es tener un mecanismo opcional de "excepción no controlada por componente". Si este mecanismo estuviera habilitado, entonces el marco haría su propia lógica try/catch en torno a todas las llamadas a los métodos de ciclo de vida del componente, los controladores de eventos y la lógica de representación. Si el marco detectó una excepción en ese nivel, consideraría que ese componente individual está muerto (y quizás lo reemplace en la interfaz de usuario con algún tipo de componente de "error"), pero no afectaría la ejecución del resto del circuito.

¿Crees que ese tipo de enfoque satisfaría tus necesidades?

Ciertamente me gusta la idea de tener un límite de componentes incorporado para errores.

Eso sería excelente. Pero creo que todavía necesitamos un método (que tenga una excepción que ocurrió como un parámetro de entrada) que podamos anular y hacer algo con esa excepción, como mostrar un cuadro de diálogo con detalles de excepción o enviar detalles de excepción al servidor donde se registraría DB o algo..
Sé que ahora se puede hacer algo similar con ILogger, pero obtenemos una cadena como parámetro de entrada y obtener algunos datos específicos de la excepción en un formato de cadena es muy difícil.

las trampas de excepción no controlada por componente serían muy buenas. Idealmente, esto sería algo que se puede especificar externamente y/o en ciertos componentes, de modo que podamos segregar partes de la interfaz de usuario o la funcionalidad en límites de error. la principal necesidad es poder hacer algo con semántica como esta:

<MyApp>
    <HandleErrors>
        <ThirdPartyComponent />
    </HandleErrors>
    <HandleErrors>
        <SomeOtherComponent />
    </HandleErrors>
</MyApp>

si alguno de los componentes no se procesa, necesitamos que el resto de la aplicación continúe. es equivalente a una aplicación de escritorio rica en datos en la que presenta una barra lateral o ejecuta alguna función de lógica de negocios, que falla, pero la aplicación no falla ni desecha los datos en los campos del formulario.

en algo como WPF, el uso de una separación estricta de vista/modelo mitiga esta preocupación; la mejor práctica es usar MVVM o MVC o lo que sea y tener un manejo de errores en torno a la lógica que se activa o actualiza la vista. sin embargo, las opiniones idiomáticas de blazor son demasiado imperativas y propensas a errores para que eso sea razonable. es difícil escribir un archivo .xaml que detenga la aplicación, pero en .razor es trivial tener una excepción no controlada durante el procesamiento , ya sea de un enlace de datos a una propiedad respaldada por ORM o simplemente porque escribió

<strong i="7">@if</strong> (mightBeNull.Value) {
    <br>
}

¿No es el ILogger ya ese lugar centralizado?

Al igual que @julienGrd , necesito una forma de capturar globalmente MsalUiRequiredException para poder redirigir al usuario a un inicio de sesión para solicitar ámbitos adicionales. En MVC hay un filtro de excepción de acción que maneja esto, pero Blazor no tiene equivalente.

¿Tal vez ILogger es el lugar donde se supone que debo hacer esto de alguna manera? Si es así, se siente mal. Mi excepción está relacionada con la autenticación, por lo que es una preocupación transversal y necesito una forma de tratarla que no contamine toda mi aplicación.

@kenchilada Sé que parece que agregar un controlador de excepciones "global" sería una solución rápida a su problema, pero cada vez que usa ese enfoque, su código pierde por completo la pista del flujo que estaba en marcha. No tiene forma de preservar el estado, y no hay forma de proporcionar una UX que no simplemente deseche lo que estaba sucediendo en ese momento. En general, es mucho mejor poner un intento/captura específico dentro de la interfaz de usuario que podría activarlo para que pueda continuar sin descartar todo el estado local.

Sin embargo, si realmente desea manejar esto a un nivel "global", entonces sí, el ILogger es una forma de hacerlo.

El problema es que el manejo basado en intentos y capturas no es posible con el modelo RenderTreeBuilder. Puedes escribir

<strong i="6">@try</strong>
{
    <p>@{throw new Exception();}</p>
}
catch (Exception e)
{
    <p>An error occurred.</p>
}

..pero no mostrará "Se produjo un error", detendrá todo el circuito. Ni siquiera obtiene el registro de la consola y #blazor-error-ui.

@SteveSandersonMS Estoy totalmente de acuerdo contigo en "teoría", pero estoy en un contexto específico en el que no sé cómo manejarlo, tal vez tengas algunas respuestas.

Sincronizo una gran cantidad de código de una aplicación de Silverlight existente, que hago la migración técnica a blazor, pero mantengo la compatibilidad y comparto el código entre las dos aplicaciones porque la cantidad de trabajo es enorme y las dos aplicaciones deben trabajar juntas durante un tiempo .

entonces mi problema es el ViewModel sincronizado en el lado del cliente, llame a servicios wcf como este:
````
public void MiFuncion(){
wcfClient.MyFunctionCompleted += MyFunctionCompleted;
wcfClient.MiFunción();
}

privado vacío MyFunctionCompleted(objeto remitente, MyFunctionCompletedArgs args){
//el resultado está aquí, y la posible excepción también
// tenemos que considerar que este código no es seguro, así que tenga una forma de atraparlo
}
````

entonces cuando llamo al método de mi modelo de vista en mi vista blazor, es inútil hacer algo como esto
private void ButtonClick(){ try{ myViewModel.MyFunction(); } catch(Exception ex){ //i can't catch the exception in the service or happened in the callback } }

Entonces, no sé cómo manejar la devolución de excepción por parte del servicio, o la excepción ocurrió directamente en la devolución de llamada, perdí la mano.

Gracias por tu ayuda !

en ese caso, podría usar un TaskCompletionSource. digamos que MyFunctionCompletedArgs contiene una excepción o un valor de tipo TResult, sería algo como esto:

public Task MyFunction() 
{
    var tcs = new TaskCompletionSource<TResult>();
    wcfClient.MyFunctionCompleted += MyFunctionCompleted(tcs);
    wcfClient.MyFunction();
    return tcs.Task;
}

private EventHandler<TResult> MyFunctionCompleted(TaskCompletionSource<TResult> tcs) => (object sender, MyFunctionCompletedArgs args) =>
{
    if (args.Error != null)
    {
        tcs.SetException(args.Error);
    }
    else
    {
        tcs.SetResult(args.ReturnValue);
    }
};

luego, en el lado de Blazor, espere a que se complete la promesa:

private async Task ButtonClick()
{
    try
    {
        await myViewModel.MyFunction();
    }
    catch (Exception ex)
    {
    }
}

Hay muchos escenarios de programación/software.

Mi conclusión de esta discusión es que Microsoft (al menos actualmente) no quiere que usemos Blazor para aplicaciones "grandes" o aplicaciones LOB, ya que esperan que coloquemos bloques de prueba/captura en todas partes.

Tal vez pueda crear aplicaciones "pequeñas" de esta manera. (también, como mencioné, no es una buena práctica)

Pero las aplicaciones LOB con muchos casos de uso y 10-20 (e incluso más) desarrolladores en un equipo no pueden funcionar así.

Por supuesto, hay más problemas con Blazor en este momento, pero este problema surgió entre 10 y 15 minutos después de comenzar a crear un POC.

Hola,

Dijo correctamente. Esperemos que Microsoft proporcione una actualización para esta última parte de este año.

Idealmente, no es posible tener un manejo de errores en todas partes y cuando el circuito se rompe, el desarrollador no sabe a dónde ir. Somos los primeros en adoptar Blazor y formamos parte de la migración de uno de los proyectos de mi empresa.

Hay muchas cosas que necesitan pulirse en Blazor.

Gracias y Saludos,

ankit bansal

Juegos científicos

De: Hagay Goshen [email protected]
Enviado: martes, 26 de mayo de 2020 00:21
Para: dotnet/aspnetcore [email protected]
CC: bansalankit2601 [email protected] ; Comentar [email protected]
Asunto: Re: [dotnet/aspnetcore] [Blazor] Manejo global de excepciones (#13452)

Hay muchos escenarios de programación/software.

Mi conclusión de esta discusión es que Microsoft (al menos actualmente) no quiere que usemos Blazor para aplicaciones "grandes" o aplicaciones LOB, ya que esperan que coloquemos bloques de prueba/captura en todas partes.

Tal vez pueda crear aplicaciones "pequeñas" de esta manera. (también, como mencioné, no es una buena práctica)

Pero las aplicaciones LOB con muchos casos de uso y 10-20 (e incluso más) desarrolladores en un equipo no pueden funcionar así.

Por supuesto, hay más problemas con Blazor en este momento, pero este problema surgió entre 10 y 15 minutos después de comenzar a crear un POC.


Estás recibiendo esto porque comentaste.
Responda a este correo electrónico directamente, véalo en GitHub https://github.com/dotnet/aspnetcore/issues/13452#issuecomment-633799650 , o cancele la suscripción https://github.com/notifications/unsubscribe-auth/ANKYSDATEUMBPN43PYQU2ZDRTM7T3ANCNFSM4IPQWA6Q . https://github.com/notifications/beacon/ANKYSDD3JBBDUMUWMZ5NQXDRTM7T3A5CNFSM4IPQWA62YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEXDQHYQ.gif

Hay muchos escenarios de programación/software.

Mi conclusión de esta discusión es que Microsoft (al menos actualmente) no quiere que usemos Blazor para aplicaciones "grandes" o aplicaciones LOB, ya que esperan que coloquemos bloques de prueba/captura en todas partes.

Tal vez pueda crear aplicaciones "pequeñas" de esta manera. (también, como mencioné, no es una buena práctica)

Pero las aplicaciones LOB con muchos casos de uso y 10-20 (e incluso más) desarrolladores en un equipo no pueden funcionar así.

Por supuesto, hay más problemas con Blazor en este momento, pero este problema surgió entre 10 y 15 minutos después de comenzar a crear un POC.

Aquí es donde aterrizamos también. Lo estamos utilizando para una interfaz de administración de back-end, pero es demasiado novedoso en este momento para ser utilizado para nuestra aplicación orientada al cliente.

@gulbanana gracias por el consejo! No estoy seguro de mantener la compatibilidad con la aplicación Silverlight con este tipo de código, pero tengo que intentarlo (incluso si prefiero una solución de manejo de excepciones global)

en ese caso, podría usar un TaskCompletionSource. digamos que MyFunctionCompletedArgs contiene una excepción o un valor de tipo TResult, sería algo como esto:

public Task MyFunction() 
{
    var tcs = new TaskCompletionSource<TResult>();
    wcfClient.MyFunctionCompleted += MyFunctionCompleted(tcs);
    wcfClient.MyFunction();
    return tcs.Task;
}

private EventHandler<TResult> MyFunctionCompleted(TaskCompletionSource<TResult> tcs) => (object sender, MyFunctionCompletedArgs args) =>
{
    if (args.Error != null)
    {
        tcs.SetException(args.Error);
    }
    else
    {
        tcs.SetResult(args.ReturnValue);
    }
};

luego, en el lado de Blazor, espere a que se complete la promesa:

private async Task ButtonClick()
{
    try
    {
        await myViewModel.MyFunction();
    }
    catch (Exception ex)
    {
    }
}

Un poco confundido aquí... Si el manejo global de excepciones no es factible, entonces ¿por qué hay un producto por ahí?
para blazor que afirma que "Todas las excepciones no detectadas se registran automáticamente"?:
https://docs.elmah.io/logging-to-elmah-io-from-blazor/

@ rono1 Ahora puede conectarse a la tubería de registro y registrar excepciones; sin embargo, eso no significa que haya "manejado" la excepción, solo que puede registrarlas globalmente. ¡Sin embargo, estoy agradecido por el registro!

Hemos movido este problema al hito de Backlog. Esto significa que no se va a trabajar en el próximo lanzamiento. Volveremos a evaluar la acumulación después del lanzamiento actual y consideraremos este elemento en ese momento. Para obtener más información sobre nuestro proceso de gestión de problemas y tener mejores expectativas con respecto a los diferentes tipos de problemas, puede leer nuestro Proceso de clasificación.

Una posibilidad que estamos considerando para el futuro es tener un mecanismo opcional de "excepción no controlada por componente". Si este mecanismo estuviera habilitado, entonces el marco haría su propia lógica try/catch en torno a todas las llamadas a los métodos de ciclo de vida del componente, los controladores de eventos y la lógica de representación. Si el marco detectó una excepción en ese nivel, consideraría que ese componente individual está muerto (y quizás lo reemplace en la interfaz de usuario con algún tipo de componente de "error"), pero no afectaría la ejecución del resto del circuito.

¿Crees que ese tipo de enfoque satisfaría tus necesidades?

@SteveSandersonMS ¿Se está considerando implementar esto? Dará como resultado una mejor experiencia de usuario y un software más robusto.

+1 en esto. ¿Realmente se supone que debemos envolver cada evento en un try/catch ? Acabo de caer en una madriguera de conejo tratando de solucionar esto con algunos componentes básicos para administrar el estado debido a lo doloroso que es esto.

+1 también en esto. El enfoque de probar/atrapar realmente no es una opción para soluciones más grandes con múltiples desarrolladores.

Abordé esto en mi aplicación blazor del lado del cliente usando un proveedor de registro personalizado:
https://github.com/markusrt/NRZMyk/blob/master/NRZMyk.Client/ReloadOnCriticalErrorLogProvider.cs

Parece un poco extraño usar un registrador como controlador de excepciones global, pero no encontré ningún enfoque más limpio a partir de ahora 😞

El equipo de Blazor definitivamente tendrá que hacer algo al respecto.
solicitud/problema.

El domingo 4 de octubre de 2020 a las 15:24, Markus Reinhardt [email protected]
escribió:

>
>
>

Abordé esto en mi aplicación blazor del lado del cliente usando un registro personalizado
proveedor:

https://github.com/markusrt/NRZMyk/blob/master/NRZMyk.Client/ReloadOnCriticalErrorLogProvider.cs

Parece un poco extraño usar un registrador como controlador de excepciones global, pero en
no encontré ningún enfoque más limpio a partir de ahora 😞


Estás recibiendo esto porque estás suscrito a este hilo.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/dotnet/aspnetcore/issues/13452#issuecomment-703255415 ,
o darse de baja
https://github.com/notifications/unsubscribe-auth/AEVARXEEHAOU532C26QCGXLSJBZRRANCNFSM4IPQWA6Q
.

Gracias por contactarnos.
Estamos moviendo este problema al hito Next sprint planning para una futura evaluación/consideración. Evaluaremos la solicitud cuando estemos planificando el trabajo para el próximo hito. Para obtener más información sobre qué esperar a continuación y cómo se manejará este problema, puede leer más sobre nuestro proceso de clasificación aquí .

Para cualquiera que busque una solución del lado del cliente:

function reportError(error) {
  if (DotNet) {
    DotNet.invokeMethodAsync('MyApp.Client', 'NotifyError', error);
  }
}

var exLog = console.error;
console.error = function (msg) {
  exLog.apply(console, arguments);
  reportError(msg);
}

window.addEventListener("unhandledrejection", function (promiseRejectionEvent) {
  reportError(promiseRejectionEvent.reason.message);
});
  public partial class AppLayout
  {
    [JSInvokable("NotifyError")]
    public static void NotifyError(string error)
    {
      //Handle errors
    }
  }

Compatibilidad con navegador

Esta es una función de importancia crítica para una aplicación de producción y no me sentiría cómodo lanzando una aplicación en la que no pudiera controlar el comportamiento de la aplicación en caso de un error no controlado, o al menos poder registrarlo de manera confiable. Afortunadamente, estoy seguro de que hay suficiente soporte para esto en JavaScript que podemos aprovechar, sin embargo, es una brecha lo suficientemente grande como para hacerme cuestionar si esta tecnología es lo suficientemente madura como para ser adoptada en aplicaciones serias.

Espero que este controlador de errores global tenga prioridad en versiones futuras.

¿Fue útil esta página
0 / 5 - 0 calificaciones