web-dev-qa-db-fra.com

Comment puis-je attraper les exceptions dans le noyau Asp.net qui se produisent dans le fil

J'ai attaché une action à certaines tâches. J'ai un middleware pour observer toutes les exceptions. Maintenant, il y a un problème avec l'exception de thread. J'ai déjà lancé manuellement une exception dans le corps de l'action, mais lorsque je lève une exception, l'application passe en mode de pause et je ne peux pas surveiller les exceptions.

Avant de configurer MVC, je mets mon middleware de gestion d'erreur 

public class ErrorHandlingMiddleware
{
    private readonly RequestDelegate next;

    public ErrorHandlingMiddleware(RequestDelegate next)
    {
        this.next = next;
    }

    public async Task Invoke(HttpContext context /* other dependencies */)
    {
        try
        {
            await next(context);
        }
        catch (Exception ex)
        {
            await HandleExceptionAsync(context, ex);
        }
    }

    private static Task HandleExceptionAsync(HttpContext context, Exception exception)
    {
        var code = HttpStatusCode.InternalServerError; 

        var result = JsonConvert.SerializeObject(new { error = exception.Message });
        context.Response.ContentType = "application/json";
        context.Response.StatusCode = (int)code;
        return context.Response.WriteAsync(result);
    }
}
//and this is the piece of code that run all tasks. 
foreach (var item in BotList)
{
            BotHandler BotObject = new BotHandler(item,conn);
            Task.Run(() => { BotObject.Run();});
}      
//

  public void Run()
    {

        //BotClient.StopReceiving();
        BotClient.OnMessage += BotOnMessageReceived;
        BotClient.OnMessageEdited += BotOnMessageReceived;
        BotClient.OnCallbackQuery += BotOnCallbackQueryReceived;

    }
     private async void BotOnMessageReceived(object sender, MessageEventArgs messageEventArgs)
    {
       try
           {
              //do something
                string a = null;
                var b = a.ToString();
           }
       catch(Exception exp )
       {
         throw exp
       }
    }
}
2
Mohsen Zahedi

Si j'ai bien compris, vous exécutez ce code en action du contrôleur:

//and this is the piece of code that run all tasks. 
foreach (var item in BotList)
{
            BotHandler BotObject = new BotHandler(item,conn);
            Task.Run(() => { BotObject.Run();});
}  

Le problème principal est que vous essayez d'exécuter la tâche pour une requête déjà terminée. C'est pourquoi ExceptionHandlingMiddleware (et en réalité d'autres middlewares) ne peut rien gérer. Pour résoudre votre problème, vous pouvez ajouter un bloc try/catch afin de gérer une exception inattendue.

Je conseillerais fortement de ne pas démarrer une tâche en arrière-plan lors d'une requête HTTP. C'est une approche sujette aux erreurs car une tâche peut être arrêtée à tout moment et vous ne le remarquerez même pas. Au lieu de cette approche, il est préférable d'utiliser une tâche en arrière-plan ( msdn , SO Discussion ), une sorte de fonction AWS lambda/Azure ou un autre planificateur de tâches.

Si vous devez effectuer un travail de recalcul après l'appel de la méthode HTTP, vous pouvez envisager le traitement des messages asynchrones pour déclencher le processus.

1
svoychik

si vous allez ici https://msdn.Microsoft.com/en-us/magazine/jj991977.aspx vous le lirez.

Les exceptions d'une méthode asynchrone Void ne peuvent pas être capturées

Donc, vous ne pouvez pas attraper l'exception (le middleware ne le peut pas) que vous lancez dans votre méthode BotOnMessageReceived (dans une partie Catch).

Donc, vous avez 2 solutions.

  1. Supprimer le mot clé asynchrone
  2. Ou attrapez les exceptions non gérées de l'application si c'est possible. Par exemple, dans une application de console .net framework normale, vous avez un événement dans App appelé des exceptions non gérées et pouvez gérer des situations similaires à la vôtre.

J'ai également trouvé ici, cela aidera peut-être Comment intercepter les exceptions non gérées dans ASP .NET Core 2.0 avant le rendu de la page?

0
Paweł Górszczak