web-dev-qa-db-fra.com

Définition du message d'une exception personnalisée sans le transmettre au constructeur de base

Je souhaite créer une exception personnalisée en C #, mais en théorie, je dois d'abord analyser un peu avant de pouvoir créer un ExceptionMessage lisible par l'homme.

Le problème est que le message d'origine ne peut être défini qu'en appelant le constructeur de base de Messsage, aussi je ne peux effectuer d'analyse préalable.

J'ai essayé de surfer sur la propriété Message comme ceci:

public class CustomException : Exception
{
    string _Message;

    public CustomException(dynamic json) : base("Plep")
    {
        // Some parsing to create a human readable message (simplified)
        _Message    = json.message;
    }

    public override string Message
    {
        get { return _Message; }
    }
}

Le problème est que le débogueur Visual Studio affiche toujours le message que j'ai transmis au constructeur, Plep dans ce cas. 

throw new CustomException( new { message="Show this message" } )

résulte en:

Visual Studio Exception Dialog

Si je laisse le constructeur de base vide, il affichera un message très générique:

Une exception non gérée du type 'App.CustomException' s'est produite dans App.exe

Question

Il semble que le dialogue Exception lit un champ/une propriété auquel je n’ai pas accès non plus. Existe-t-il un autre moyen de définir un message d'erreur lisible par l'homme en dehors du constructeur de base sur Exception.

Notez que j'utilise Visual Studio 2012.

40
Dirk Boer

Il suffit de mettre le code de formatage dans une méthode statique?

public CustomException(dynamic json) : base(HumanReadable(json)) {}
private static string HumanReadable(dynamic json) {
    return whatever you need to;
}
76
Sebastian Redl

Prenez en compte les directives de Microsoft pour la création de nouvelles exceptions:

  using System;
  using System.Runtime.Serialization;

  [Serializable]
  public class CustomException : Exception
  {
    //
    // For guidelines regarding the creation of new exception types, see
    //    https://msdn.Microsoft.com/en-us/library/ms229064(v=vs.100).aspx
    //

    public CustomException()
    {
    }

    public CustomException(string message) : base(message)
    {
    }

    public CustomException(string message, Exception inner) : base(message, inner)
    {
    }

    protected CustomException(SerializationInfo info, StreamingContext context) : base(info, context)
    {
    }

    public static CustomException FromJson(dynamic json)
    {
      string text = ""; // parse from json here

      return new CustomException(text);
    }
  }

Notez la méthode fabrique statique (ne faisant pas partie du motif), que vous pouvez utiliser dans votre programme comme ceci:

throw CustomException.FromJson(variable);

De cette façon, vous avez suivi les meilleures pratiques et pouvez analyser votre JSON dans la classe des exceptions.

14
nvoigt

Je pense que le problème peut être avec le débogueur de Visual Studio. J'ai eu les mêmes résultats que vous avez obtenus avec le débogueur, mais quand j'imprime le message:

class CustomException : Exception {
    public CustomException(dynamic json)
        : base("Plep") {
            _Message = json.message;
    }

    public override string Message {
        get { return _Message; }
    }

    private string _Message;
}

class Program {
    static void Main(string[] args) {
        try {
            throw new CustomException(new { message = "Show this message" });
        } catch (Exception ex) {
            Console.WriteLine(ex.Message);
        }
    }
}

Je reçois le "Show this message" attendu.

Si vous mettez un point d'arrêt où l'exception est interceptée, le débogueur vous montrera le message correct.

7
Ferruccio

J'aime utiliser ceci ici. C'est facile et n'a pas besoin de la fonction static:

public class MyException : Exception
{
    public MyException () : base("This is my Custom Exception Message")
    {
    }
}
1
Simons0n

Quel est le problème avec quelque chose comme ça.

    public class FolderNotEmptyException : Exception
{

    public FolderNotEmptyException(string Path) : base($"Directory is not empty. '{Path}'.")
    { }

    public FolderNotEmptyException(string Path, Exception InnerException) : base($"Directory is not empty. '{Path}'.", InnerException)
    { }

}

Je viens d'utiliser une chaîne et inclure des paramètres. Solution simple.

0
Kieran Foot