C# – Come creare un'eccezione personalizzata

C# – Come creare un'eccezione personalizzata

Per creare un'eccezione personalizzata, crea una sottoclasse della classe Exception, come questa:

public class SimpleCustomException : Exception
{
	public SimpleCustomException(string message) : base(message) { }
	public SimpleCustomException() { }
}
Code language: C# (cs)

Quindi lancialo proprio come faresti con qualsiasi altra eccezione, come questa:

throw new SimpleCustomException("Cannot call this method on days that end with 'y'")
Code language: C# (cs)

È una buona idea passare un messaggio di errore personalizzato al costruttore di base. Se questa eccezione non è gestita, o se stai registrando l'eccezione, mostrerà il nome dell'eccezione e il messaggio, come questo:

SimpleCustomException: Cannot call this method on days that end with 'y'Code language: plaintext (plaintext)

Esempio:viene generata un'eccezione personalizzata quando vengono passati dati non validi

La creazione di eccezioni personalizzate consente di creare eccezioni molto specifiche. La generazione e la cattura di eccezioni molto specifiche fa parte di una gestione pulita degli errori.

L'esempio seguente mostra una classe di parser di stringhe binarie che genera un'eccezione personalizzata quando vengono passati dati non validi. Genera un'eccezione molto specifica che spiega esattamente qual è il problema e quali dati sono previsti.

1 – Aggiungi una classe di eccezione personalizzata

Questa eccezione personalizzata sta prendendo il binaryString non valido e lo inserisce in un messaggio di errore che spiega qual è il formato previsto e include un esempio di input valido.

public class InvalidBinaryStringException : Exception
{
	public InvalidBinaryStringException(string binaryString)
		: base($"Bad binary string: {binaryString}. Binary string must be 0's and 1's and the length must be a multiple of 8. Example: 00000001.")
	{
	}
}
Code language: C# (cs)

2 – Genera l'eccezione quando vengono rilevate condizioni di errore

Prima di provare ad analizzare la stringa binaria, la classe BinaryStringUtil controlla il passato in binaryString e genera l'eccezione InvalidBinaryStringException personalizzata se l'input non è valido.

public class BinaryStringUtil
{
	public static byte[] Parse(string binaryString)
	{
		if (binaryString.Length % 8 != 0 || Regex.IsMatch(binaryString, "[^01]"))
		{
			throw new InvalidBinaryStringException(binaryString);
		}

		//Parse binaryString into byte[]
		
		return new byte[] { };

	}
}
Code language: C# (cs)

Ti starai chiedendo, perché non lanciare invece ArgumentException o FormatException? È vero, potresti generare queste eccezioni e passare lo stesso messaggio di errore. Tuttavia, considera i seguenti motivi per l'utilizzo di eccezioni personalizzate:

  • Raccogli i messaggi di errore. Nota come il codice sopra sta semplicemente passando in binaryString all'eccezione?
  • Supponiamo che tu stia utilizzando uno strumento di monitoraggio dei log (come Splunk) e desideri inviare e-mail di avviso quando si verifica questo errore specifico. Puoi semplicemente cercare "InvalidBinaryStringException" nel registro. Se stavi usando ArgumentException, dovresti invece cercare il messaggio di errore ("Stringa binaria errata...").
  • Il codice client può catturare InvalidBinaryStringException e gestirlo correttamente. Diciamo che il tuo codice di analisi ha un bug e qualche metodo che stai chiamando sta lanciando ArgumentException. Se il client rilevasse questa eccezione non specifica, il codice client avrebbe un comportamento di gestione degli errori errato e il tuo bug sarebbe nascosto.

3 – Aggiungi unit test per dimostrare che il codice genera eccezioni

I seguenti unit test parametrizzati verificano le due condizioni di errore:quando la stringa binaria non ha una lunghezza valida e quando ha caratteri non validi. Si noti che sta usando Assert.ThrowsException invece dell'attributo ExpectedException.

[DataRow("01")]
[DataRow("0100000a")]
[TestMethod()]
public void ParseTest_WhenBadBinaryString_ThrowsException(string binaryString)
{
   Assert.ThrowsException<InvalidBinaryStringException>(() => BinaryStringUtil.Parse(binaryString));
}

Code language: C# (cs)