Aspnetcore: Gestion globale des exceptions

Créé le 26 août 2019  ·  51Commentaires  ·  Source: dotnet/aspnetcore

Bonjour les gars, je voulais savoir quelle est la meilleure façon d'attraper une exception au niveau de l'application, d'éviter de mettre try catch dans toutes mes méthodes et composants, et de centraliser la gestion des exceptions en un point (généralement afficher une notification d'erreur et enregistrer l'exception) .

il y a donc une meilleure façon de faire cela dans preview8, ou quelque chose de prévu pour la RTM ?

Merci !

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

Commentaire le plus utile

Une mise à jour sur ce problème ?

Actuellement, mon application blazor côté serveur vient de cesser de répondre aux entrées de l'utilisateur après la levée d'une exception.

Ce n'est pas une bonne pratique de couvrir toutes les lignes de code avec try-catch (ni de s'attendre à ce que le développeur le fasse), en cas d'exception "non prévue", nous devrions avoir un gestionnaire générique qui nous permet :

1.Choisissez si vous souhaitez couper le circuit.
2. Montrez à notre utilisateur un message d'interface graphique "convivial" ou redirigez-le simplement vers une page d'erreur générique.

Actuellement, après une exception non gérée, l'application ne peut pas informer l'utilisateur d'un problème et l'utilisateur ne peut que relancer l'application (fermer le navigateur et accéder à nouveau à l'URL de l'application) ou actualiser la page et perdre tout l'état (qui est parfois bon , mais le développeur de l'application doit choisir cela).

Tous les 51 commentaires

Toutes les exceptions non gérées doivent se retrouver dans le Logger. Si vous voyez le contraire, veuillez nous en informer et nous serons heureux d'enquêter. Regarder les journaux devrait être la voie à suivre ici.

OK, ce que je comprends, c'est que je dois fournir ma propre implémentation d'ILogger ? et c'est sur ma mise en œuvre que je dois faire face à l'exception ? (par exemple, afficher la notification, écrire une exception dans un fichier côté serveur et l'envoyer au contrôleur côté client)
en fait, la seule chose si trouvée est ce paquet https://github.com/BlazorExtensions/Logging
Je ne comprends pas vraiment comment l'utiliser, il semble que nous ne pouvons nous connecter à la console qu'avec cela.

Mais même avec cette extension, s'il y a une exception non gérée dans le code, l'application plante.

donc si j'ai bien compris, je n'ai pas le choix d'entourer tout mon code de try catch ?

Merci pour votre explication

L'un des fournisseurs de journalisation répertoriés ici : https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-2.2#built -in-logging-providers ainsi que les fournisseurs développés par la communauté ( https://github.com/aspnet/Extensions/tree/master/src/Logging#providers) devrait fonctionner.

Mais même avec cette extension, s'il y a une exception non gérée dans le code, l'application plante.

Pour Blazor côté serveur, une exception non gérée doit déconnecter le circuit, mais pas planter l'application. Si un bloc est destiné à lever une exception que vous pouvez tolérer, un try-catch semble être la manière la plus raisonnable de procéder. Que comptez-vous faire avec les exceptions non gérées si vous interceptez une exception arbitraire ?

Blazor côté client n'enregistre aucune exception. Ils sont juste imprimés sur la console. Voici le code 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);
    }
}

Le seul moyen que j'ai trouvé pour intercepter les exceptions est décrit ici
https://remibou.github.io/Exception-handling-in-Blazor/

Mais je n'appellerais pas cela la gestion des exceptions...

J'aimerais avoir un gestionnaire d'exception global pour pouvoir écrire mon code sans blocs catch ...

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

Si la méthode SomeAsync lève une exception, mon varialbe IsLoading est défini sur false mais ma vue n'est pas restituée. Vous devez appeler SetStateHasChanged dans le bloc finally pour forcer le rendu de la vue

pour le blazor côté client, j'écris enfin ma propre implémentation sur ILogger (inspirée du code d'implémentation par défaut qui se connecte à la console).
Avec cette implémentation, je peux appeler un LoggerController sur mon serveur, auquel un ILogger est également injecté (mais cette fois, c'est une implémentation NLog qui est injectée, donc je peux écrire correctement toutes les exceptions sur le serveur)

J'abandonne l'idée d'une gestion globale des exceptions, qui ne semble pas être la logique de blazor, et mets try/catch partout et injecte un ILoggerdans tous les composants.

Sauf si vous pensez qu'il y a mieux à faire, vous pouvez clore ce sujet.

Je pense que c'est une fonctionnalité manquante.. Lorsqu'une exception est levée, j'aimerais également avoir un emplacement centralisé pour capturer toutes les exceptions non gérées et faire quelque chose.. Soit l'afficher dans une fenêtre contextuelle, l'enregistrer quelque part, l'envoyer au serveur ou quoi que ce soit .. sans nuire à l'état de l'application
Quelque chose comme l'événement UnhandledException dans WPF
https://docs.microsoft.com/en-us/dotnet/api/system.appdomain.unhandledexception?redirectedfrom=MSDN&view=netframework-4.8

Le ILogger n'est-il pas déjà cet endroit centralisé ?

@SteveSandersonMS regarde mon commentaire ci-dessus
https://github.com/aspnet/AspNetCore/issues/13452#issuecomment -535227410
Les exceptions (dans le blazor côté client) sont écrites sur la console à l'aide de Console.Error.WriteLine, elles ne sont pas enregistrées à l'aide de ILogger.. Vous pouvez implémenter un TextWriter personnalisé et remplacer Console.Error
https://remibou.github.io/Exception-handling-in-Blazor/
mais vous obtenez une représentation sous forme de chaîne d'une exception. Analyser cette chaîne, qui inclut une trace de pile, et essayer d'obtenir (par exemple) uniquement un message d'exception est au moins fastidieux.
Je voudrais obtenir un accès à l'objet d'exception afin que je puisse faire ma propre journalisation (ou quoi que ce soit)

@rborosak Merci pour la clarification!

Une mise à jour sur ce problème ?

Actuellement, mon application blazor côté serveur vient de cesser de répondre aux entrées de l'utilisateur après la levée d'une exception.

Ce n'est pas une bonne pratique de couvrir toutes les lignes de code avec try-catch (ni de s'attendre à ce que le développeur le fasse), en cas d'exception "non prévue", nous devrions avoir un gestionnaire générique qui nous permet :

1.Choisissez si vous souhaitez couper le circuit.
2. Montrez à notre utilisateur un message d'interface graphique "convivial" ou redirigez-le simplement vers une page d'erreur générique.

Actuellement, après une exception non gérée, l'application ne peut pas informer l'utilisateur d'un problème et l'utilisateur ne peut que relancer l'application (fermer le navigateur et accéder à nouveau à l'URL de l'application) ou actualiser la page et perdre tout l'état (qui est parfois bon , mais le développeur de l'application doit choisir cela).

@hagaygo Très bon résumé !

@SteveSandersonMS Veuillez considérer ceci pour le jalon 3.1.x ! Veuillez ne pas déplacer ceci vers 5.0.0

Salut,

J'obtiens ce genre d'erreur lorsque le circuit s'interrompt dans la console de la fenêtre du développeur.

image

Je ne pense pas qu'il y ait de toute façon actuellement qui puisse informer l'utilisateur qu'une erreur s'est produite après cela dans l'écran et demander de l'actualiser sans ouvrir manuellement la fenêtre du développeur pour vérifier et actualiser la page

@SteveSandersonMS Pourriez-vous préciser si le app.UseExceptionHandler() fonctionne ou non pour Blazor côté serveur?

J'ai vu plusieurs cas où mon ErrorHandler personnalisé n'attrape pas les exceptions levées par mon application. Exemple de code

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 exemple est lorsque mon référentiel lève une exception en tant que telle :
The instance of entity type cannot be tracked because another instance with the same key value for {'Id'} is already being tracked

Ma solution MVC attrape toutes les exceptions et utilise des implémentations ErrorHandling similaires.

Déplacez ceci vers la version 5.0 pour distiller les demandes spécifiques ici et voir si nous pouvons répondre à certaines d'entre elles.

le plus gros problème pour moi est les limites d'erreur . Je veux pouvoir utiliser un composant tiers et, d'une manière ou d'une autre, envelopper mon utilisation de ce composant dans la gestion des erreurs afin qu'un bogue dans la bibliothèque ne tue pas toute mon application Web. pour le moment, il n'y a pas de "place pour mettre la capture d'essai" - l'ensemble de l'arborescence des composants est supervisée par le moteur de rendu blazor, qui mourra si quelque chose de profond dans l'arborescence se gâte.

+1 pour cette fonctionnalité.
Devoir mettre un bloc try/catch dans toutes les méthodes n'est pas une solution raisonnable.

Personnellement, j'avais l'habitude de lancer une exception pour gérer les erreurs métier. A haut niveau, j'attrape l'exception et en fonction de son type, je décide si l'exception doit être journalisée, affichée à l'utilisateur et si affichée si j'affiche le message complet (exceptions métier) ou juste un "Quelque chose ne va pas") .

En fait, le seul moyen que j'ai trouvé pour faire quelque chose comme ça est de créer une classe ComponentBaseEx qui hérite de ComponentBase et remplace OnInitialized(Async), OnParametersSet(Async), ...
Malheureusement, même avec ce chemin à parcourir, je dois gérer manuellement toutes les actions de l'utilisateur (supprimer un client, ...)

Penses-tu
1) quelque chose peut être fait ?
2) si oui, quand ?

Voici mon scénario : Application de bureau/hybride Blazor utilisant le serveur Blazor. Un utilisateur connecté à la fois et l'état persiste à travers les rechargements. Ainsi, s'il existe une exception non gérée, il n'y a aucun moyen de remettre l'application dans un état fiable autre que de la redémarrer. Nous devons intercepter les exceptions non gérées, afficher l'UX appropriée, puis fermer. Modèle d'application de bureau standard.

Hack temporaire : nous avons mis en place une journalisation avec Serilog. Serilog dispose d'une API qui vous permet de filtrer tous les messages du journal et de décider s'ils sont émis. Nous abusons de cette API en vérifiant si un événement de journal a une clé CircuitId dans son dictionnaire de propriétés. Si c'est le cas, cela signifie qu'un circuit est mort - c'est-à-dire qu'il y a une exception non gérée. Nous pouvons extraire l'exception incriminée de l'objet de message de journal que nous avons examiné. Presto - vous avez la main sur l'exception non gérée tout en haut et vous pouvez en faire ce que vous voulez.

Bonjour les gars, comme les autres, je suis vraiment inquiet si vous déplacez cela vers le jalon .NET 5.
Après un an de travail sur blazor en réécrivant une ancienne application silverlight, je suis supposé déployer mon application en production en mai/juin (lorsque webassembly sera prêt pour la production).

Mais je ne peux définitivement pas le faire sans un moyen efficace de détecter ou au moins de consigner toutes les erreurs inattendues.

Veuillez envisager de créer quelque chose, même pas parfait, avant la version 5.0 (juste une méthode à l'exception est OK pour moi, au moins nous pouvons nous connecter ...)

Merci beaucoup !

Bonjour, je suis dans le même cas que @julienGrd
Merci de faire quelque chose pour nous aider/nous guider.
Salutations!

Il en va de même pour moi.

Nous avons utilisé Blazor Server pour tout notre développement et migré de
les anciennes pages Web ASP.Net.

Le mar 3 mars 2020 à 12 h 02 eliudgerardo [email protected]
a écrit:

Bonjour, je suis dans le même cas que @julienGrd
https://github.com/julienGrd
Merci de faire quelque chose pour nous aider/nous guider.
Salutations!


Vous recevez ceci parce que vous avez commenté.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/dotnet/aspnetcore/issues/13452?email_source=notifications&email_token=ANKYSDFSUQ3OTBGWQMRV5EDRFUZ27A5CNFSM4IPQWA62YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOENUJXLA#issuecomment-55
ou désabonnez-vous
https://github.com/notifications/unsubscribe-auth/ANKYSDGFCDRMZV2N4NLMOMLRFUZ27ANCNFSM4IPQWA6Q
.

--
Ankit Bansal

*Jeux Scientifiques*

L'intention est que vous puissiez enregistrer toutes les exceptions non interceptées à l'aide de l'interface ILogger . Cela signifie que vous pouvez brancher votre propre système de journalisation personnalisé qui fait ce que vous voulez avec les informations d'exception.

Cependant , il y a encore une partie de cela que nous n'avons pas encore implémentée. Ceci est suivi par https://github.com/dotnet/aspnetcore/issues/19533. Nous ne manquerons pas de le faire bientôt.

vous devriez pouvoir enregistrer toutes les exceptions non interceptées à l'aide de l'interface ILogger

@SteveSandersonMS Je pense que ce que nous recherchons ici est une API beaucoup plus générale, qui vous donne juste une exception non interceptée pour faire ce que nous voulons _avec l'exception elle-même._ Imaginez que nous voulons examiner l'exception et éventuellement réagir d'une manière ou d'une autre, peut-être envoyer le exception à un service de suivi des exceptions comme Raygun, ou présenter une interface utilisateur basée sur le contenu. Sans une telle API, nous devons abuser de l'interface ILogger pour accomplir toutes ces choses, ce qui est gênant. Pourquoi ne pas simplement fournir cette API beaucoup plus générale, au lieu de forcer tous les scénarios possibles via une implémentation ILogger ?

L'intention est que vous puissiez enregistrer toutes les exceptions non interceptées à l'aide de l'interface ILogger . Cela signifie que vous pouvez brancher votre propre système de journalisation personnalisé qui fait ce que vous voulez avec les informations d'exception.

@SteveSandersonMS Par hasard, avez-vous un exemple de référence pour le faire dans une application Server Side Blazor ? Mon intention est, après avoir enregistré une exception non interceptée, d'afficher un message convivial à l'utilisateur. L'aide sera appréciée. Salutations.

@eliudgerardo Blazor Server affiche déjà une interface utilisateur face à l'utilisateur lorsqu'il y a une erreur non gérée. Vous pouvez personnaliser cette interface utilisateur. Les documents à ce sujet sont à https://docs.microsoft.com/en-us/aspnet/core/blazor/handle-errors?view=aspnetcore-3.1#detailed -errors-during-development

@SteveSandersonMS Je suis au courant de cette option que vous mentionnez, mais je crains que dans ce cas, le circuit de connexion ne soit interrompu et je ne souhaite pas envelopper tous mes appels d'API avec try/catch. Y a-t-il donc un moyen d'y parvenir?

@eliudgerardo Pourquoi est-il important que le circuit soit interrompu ? Votre objectif est-il de laisser l'utilisateur continuer à utiliser le circuit même après l'exception non gérée ?

@SteveSandersonMS Nous ne voulons pas que le circuit se brise !. Si une exception se produit (dans notre application ou quelque part dans la bibliothèque tierce que nous utilisons), nous aimerions un endroit où nous pourrions afficher une boîte de dialogue indiquant "Quelque chose s'est mal passé {exception.Message}" et l'application continuerait à fonctionner. Nous avons une solution partielle à cela, envelopper les méthodes de cycle de vie et nos méthodes dans le bloc try catch, mais c'est lourd et il y a un problème avec les bibliothèques tierces...

@partyelite Si une exception n'est pas gérée, alors ce circuit est maintenant dans un état inconnu. Nous ne pouvons plus dire si les ressources qu'il contient sont encore utilisables, si votre logique de sécurité a été entièrement exécutée ou quoi que ce soit d'autre. Si le circuit continuait à être utilisé, cela pourrait créer un comportement indéfini, y compris des problèmes de sécurité potentiels, qui sont problématiques étant donné que ce code s'exécute sur votre serveur.

Une possibilité que nous envisageons pour l'avenir est d'avoir un mécanisme facultatif « d'exception non gérée par composant ». Si ce mécanisme était activé, le framework exécuterait sa propre logique try/catch autour de tous les appels dans les méthodes de cycle de vie, les gestionnaires d'événements et la logique de rendu du composant. Si le framework attrapait une exception à ce niveau, il considérerait ce composant individuel comme mort (et le remplacerait peut-être dans l'interface utilisateur par une sorte de composant "d'erreur") mais n'affecterait pas l'exécution du reste du circuit.

Pensez-vous que ce genre d'approche répondrait à vos besoins?

J'aime certainement l'idée d'avoir une limite de composant intégrée pour les erreurs.

Ce serait excellent. Mais je pense que nous avons toujours besoin d'une méthode (qui a une exception qui s'est produite en tant que paramètre d'entrée) que nous pourrions remplacer et faire quelque chose avec cette exception - comme afficher une boîte de dialogue avec les détails de l'exception ou envoyer les détails de l'exception au serveur où il serait connecté à DB ou autre..
Je sais que quelque chose de similaire peut maintenant être fait en utilisant ILogger mais nous obtenons une chaîne comme paramètre d'entrée et obtenir des données spécifiques de l'exception dans un format de chaîne est vraiment difficile.

les interruptions d'exception non gérées par composant seraient très bonnes. idéalement, ce serait quelque chose qui peut être spécifié de manière externe et/ou dans certains composants, afin que nous puissions séparer des parties de l'interface utilisateur ou des fonctionnalités dans des limites d'erreur. la principale nécessité est de pouvoir faire quelque chose avec une sémantique comme celle-ci :

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

si l'un des composants ne parvient pas à s'afficher, nous avons besoin que le reste de l'application soit pour continuer. cela équivaut à une application de bureau riche en données dans laquelle vous présentez une barre latérale ou exécutez une fonction de logique métier, qui échoue, mais l'application ne plante pas et ne supprime pas les données dans les champs de formulaire.

dans quelque chose comme WPF, l'utilisation d'une séparation vue/modèle stricte atténue ce problème ; la meilleure pratique consiste à utiliser MVVM ou MVC ou autre et à gérer les erreurs autour de la logique déclenchée par ou qui met à jour la vue. cependant, les vues idiomatiques blazor sont trop impératives et sujettes aux erreurs pour que cela soit raisonnable. il est difficile d'écrire un fichier .xaml qui arrêtera l'application, mais dans .razor, il est trivial d'avoir une exception non gérée lors du rendu , que ce soit à partir d'une liaison de données à une propriété basée sur ORM ou simplement parce que vous avez écrit

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

Le ILogger n'est-il pas déjà cet endroit centralisé ?

Comme @julienGrd, j'ai besoin d'un moyen d'attraper globalement MsalUiRequiredException afin de pouvoir rediriger l'utilisateur vers une connexion pour demander des étendues supplémentaires. Dans MVC, il existe un filtre d'exception d'action qui gère cela, mais Blazor n'a pas d'équivalent.

Peut-être que ILogger est l'endroit où je suis censé faire ça d'une manière ou d'une autre ? Si c'est le cas, ça fait mal. Mon exception est liée à l'authentification, il s'agit donc d'une préoccupation transversale et j'ai besoin d'un moyen de la gérer qui ne pollue pas l'ensemble de mon application.

@kenchilada Je sais que l'ajout d'un gestionnaire d'exceptions "global" serait une solution rapide à votre problème, mais chaque fois que vous utilisez cette approche, votre code perd complètement la trace du flux en cours. Vous n'avez aucun moyen de préserver l'état, et aucun moyen de fournir une UX qui ne se contente pas de jeter tout ce qui se passait à l'époque. En général, il est préférable de mettre un try/catch spécifique dans l'interface utilisateur qui pourrait le déclencher afin que vous puissiez continuer sans supprimer tout l'état local.

Cependant, si vous voulez vraiment gérer cela à un niveau "global", alors oui, le ILogger est un moyen de le faire.

Le problème est que la gestion basée sur try-catch n'est pas possible avec le modèle RenderTreeBuilder. Tu peux écrire

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

..mais il n'affichera pas "Une erreur s'est produite.", cela fera tomber tout le circuit. Vous n'obtenez même pas le journal de la console et #blazor-error-ui.

@SteveSandersonMS Je suis totalement d'accord avec vous en "théorie" mais je suis dans un contexte spécifique où je ne sais pas comment le gérer, peut-être aurez-vous des réponses.

Je synchronise beaucoup de code à partir d'une application silverlight existante, dont je fais la migration technique vers blazor, mais garde la compatibilité et partage le code entre les deux applications car la quantité de travail est énorme et les deux applications doivent fonctionner côte à côte pendant un certain temps .

donc mon problème est le ViewModel synchronisé côté client appeler les services wcf comme ceci :
````
public void MaFonction(){
wcfClient.MyFunctionCompleted += MyFunctionCompleted ;
wcfClient.MaFonction();
}

private void MyFunctionCompleted(object sender, MyFunctionCompletedArgs args){
// le résultat est là, et l'exception potentielle aussi
// nous devons considérer que ce code n'est pas sûr, alors ayez un moyen de l'attraper
}
````

donc quand j'appelle la méthode de mon modèle de vue dans ma vue blazor, il est inutile de faire quelque chose comme ça
private void ButtonClick(){ try{ myViewModel.MyFunction(); } catch(Exception ex){ //i can't catch the exception in the service or happened in the callback } }

Donc, je ne sais pas comment gérer le retour d'exception par le service, ou une exception s'est produite directement dans le rappel, j'ai perdu la main.

Merci pour ton aide !

dans ce cas, vous pouvez en fait utiliser un TaskCompletionSource. disons que MyFunctionCompletedArgs contient soit une exception, soit une valeur de type TResult, ce serait quelque chose comme ceci :

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);
    }
};

puis côté Blazor, attendez que la promesse soit remplie :

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

Il existe de nombreux scénarios de programmation/logiciels.

Ma conclusion de cette discussion est que Microsoft (du moins actuellement) ne veut pas que nous utilisions Blazor pour les "grosses" applications ou les applications LOB car ils s'attendent à ce que nous mettions des blocs try/catch partout.

Vous pouvez peut-être créer une "petite" application de cette manière. (aussi, comme je l'ai mentionné, ce n'est pas une bonne pratique)

Mais les applications LOB avec de nombreux cas d'utilisation et 10 à 20 (et même plus) développeurs dans une équipe ne peuvent pas fonctionner comme ça.

Il y a bien sûr plus de problèmes avec Blazor pour le moment, mais ce problème est survenu environ 10 à 15 minutes après avoir commencé à créer un POC.

Salut,

A juste titre dit. Espérons que Microsoft fournira une mise à jour pour cette dernière partie de cette année.

Idéalement, il n'est pas possible d'avoir une gestion des erreurs partout et lorsque le circuit se rompt, le développeur ne sait pas où aller. Nous sommes les premiers à adopter Blazor et avons fait partie de la migration pour l'un de mes projets d'entreprise.

Il y a beaucoup de choses qui doivent être peaufinées dans Blazor.

Merci & Cordialement,

Ankit Bansal

Jeux scientifiques

De : Hagay Goshen [email protected]
Envoyé : mardi 26 mai 2020 00:21
À : dotnet/aspnetcore [email protected]
Cc : bansalankit2601 [email protected] ; Commentaire [email protected]
Objet : Re : [dotnet/aspnetcore] [Blazor] Gestion globale des exceptions (#13452)

Il existe de nombreux scénarios de programmation/logiciels.

Ma conclusion de cette discussion est que Microsoft (du moins actuellement) ne veut pas que nous utilisions Blazor pour les "grosses" applications ou les applications LOB car ils s'attendent à ce que nous mettions des blocs try/catch partout.

Vous pouvez peut-être créer une "petite" application de cette manière. (aussi, comme je l'ai mentionné, ce n'est pas une bonne pratique)

Mais les applications LOB avec de nombreux cas d'utilisation et 10 à 20 (et même plus) développeurs dans une équipe ne peuvent pas fonctionner comme ça.

Il y a bien sûr plus de problèmes avec Blazor pour le moment, mais ce problème est survenu environ 10 à 15 minutes après avoir commencé à créer un POC.


Vous recevez ceci parce que vous avez commenté.
Répondez directement à cet e-mail, consultez-le sur GitHub https://github.com/dotnet/aspnetcore/issues/13452#issuecomment-633799650 , ou désabonnez-vous https://github.com/notifications/unsubscribe-auth/ANKYSDATEUMBPN43PYQU2ZDRTM7T3ANCNFSM4IPQWA6Q . https://github.com/notifications/beacon/ANKYSDD3JBBDUMUWMZ5NQXDRTM7T3A5CNFSM4IPQWA62YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEXDQHYQ.gif

Il existe de nombreux scénarios de programmation/logiciels.

Ma conclusion de cette discussion est que Microsoft (du moins actuellement) ne veut pas que nous utilisions Blazor pour les "grosses" applications ou les applications LOB car ils s'attendent à ce que nous mettions des blocs try/catch partout.

Vous pouvez peut-être créer une "petite" application de cette manière. (aussi, comme je l'ai mentionné, ce n'est pas une bonne pratique)

Mais les applications LOB avec de nombreux cas d'utilisation et 10 à 20 (et même plus) développeurs dans une équipe ne peuvent pas fonctionner comme ça.

Il y a bien sûr plus de problèmes avec Blazor pour le moment, mais ce problème est survenu environ 10 à 15 minutes après avoir commencé à créer un POC.

C'est aussi là que nous avons atterri. Nous l'utilisons pour une interface d'administration backend, mais il est beaucoup trop nouveau pour le moment pour être utilisé pour notre application orientée client.

@gulbanana merci pour le conseil ! Je ne suis pas sûr de garder la compatibilité avec l'application silverlight avec ce type de code, mais je dois essayer (même si je préfère une solution globale de gestion des exceptions)

dans ce cas, vous pouvez en fait utiliser un TaskCompletionSource. disons que MyFunctionCompletedArgs contient soit une exception, soit une valeur de type TResult, ce serait quelque chose comme ceci :

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);
    }
};

puis côté Blazor, attendez que la promesse soit remplie :

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

Un peu confus ici ... Si la gestion globale des exceptions n'est pas faisable, alors pourquoi y a-t-il un produit là-bas
pour blazor qui prétend que "Toutes les exceptions non interceptées sont automatiquement enregistrées" ? :
https://docs.elmah.io/logging-to-elmah-io-from-blazor/

@ rono1 Vous pouvez maintenant vous connecter au pipeline de journalisation et enregistrer les exceptions - cela ne signifie pas pour autant que vous avez "géré" l'exception, mais simplement que vous pouvez les enregistrer globalement. Je suis reconnaissant pour la journalisation, cependant!

Nous avons déplacé ce problème vers le jalon Backlog. Cela signifie qu'il ne sera pas travaillé pour la prochaine version. Nous réévaluerons l'arriéré après la version actuelle et examinerons cet élément à ce moment-là. Pour en savoir plus sur notre processus de gestion des problèmes et avoir de meilleures attentes concernant les différents types de problèmes, vous pouvez lire notre processus de triage .

Une possibilité que nous envisageons pour l'avenir est d'avoir un mécanisme facultatif « d'exception non gérée par composant ». Si ce mécanisme était activé, le framework exécuterait sa propre logique try/catch autour de tous les appels dans les méthodes de cycle de vie, les gestionnaires d'événements et la logique de rendu du composant. Si le framework attrapait une exception à ce niveau, il considérerait ce composant individuel comme mort (et le remplacerait peut-être dans l'interface utilisateur par une sorte de composant "d'erreur") mais n'affecterait pas l'exécution du reste du circuit.

Pensez-vous que ce genre d'approche répondrait à vos besoins?

@SteveSandersonMS Est-ce que cela est envisagé pour la mise en œuvre ? Il en résultera une meilleure expérience utilisateur et un logiciel plus robuste.

+1 à ce sujet. Nous sommes vraiment censés envelopper chaque événement dans un try/catch ? Je viens de descendre dans un terrier de lapin en essayant de contourner ce problème avec certains composants de base pour gérer l'état à cause de la douleur que cela représente.

+1 aussi à ce sujet. L'approche try/catch n'est vraiment pas une option pour les solutions plus importantes avec plusieurs développeurs.

J'ai adressé cela dans mon application blazor côté client en utilisant un fournisseur de journalisation personnalisé :
https://github.com/markusrt/NRZMyk/blob/master/NRZMyk.Client/ReloadOnCriticalErrorLogProvider.cs

Il semble un peu bizarre d'utiliser un enregistreur comme gestionnaire d'exceptions global, mais je n'ai pas trouvé d'approche plus propre pour l'instant 😞

L'équipe Blazor devra définitivement faire quelque chose à ce sujet
demande/problème.

Le dimanche 4 octobre 2020 à 15:24, Markus Reinhardt [email protected]
a écrit:

>
>
>

J'ai adressé cela dans mon application blazor côté client en utilisant une journalisation personnalisée
fournisseur:

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

Il semble un peu bizarre d'utiliser un enregistreur comme gestionnaire d'exceptions global mais à I
n'a pas trouvé d'approche plus propre pour le moment 😞


Vous recevez ceci parce que vous êtes abonné à ce fil.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/dotnet/aspnetcore/issues/13452#issuecomment-703255415 ,
ou désabonnez-vous
https://github.com/notifications/unsubscribe-auth/AEVARXEEHAOU532C26QCGXLSJBZRRANCNFSM4IPQWA6Q
.

Merci de nous avoir contacté.
Nous déplaçons ce problème au jalon Next sprint planning pour une évaluation / considération future. Nous évaluerons la demande lors de la planification des travaux pour la prochaine étape. Pour en savoir plus sur ce à quoi vous attendre ensuite et sur la manière dont ce problème sera traité, vous pouvez en savoir plus sur notre processus de triage ici .

Pour tous ceux qui recherchent une solution de contournement côté client :

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
    }
  }

Prise en charge du navigateur

Il s'agit d'une fonctionnalité extrêmement importante pour une application de production et je ne me sentirais pas à l'aise de publier une application où je ne pourrais pas contrôler le comportement de l'application en cas d'erreur non gérée, ou au moins être en mesure de la consigner de manière fiable. Heureusement, je suis sûr qu'il y a suffisamment de support pour cela dans JavaScript que nous pouvons exploiter, mais c'est un écart suffisamment important pour que je me demande si cette technologie est vraiment suffisamment mature pour être adoptée dans des applications sérieuses.

J'espère que ce gestionnaire d'erreurs global sera prioritaire dans les futures versions.

Cette page vous a été utile?
0 / 5 - 0 notes