Custom Exception handing with Property class in C#
I know this is already asked question.I need to develop User Defined Exception Handing along with the property class, But i am not retrieving the newly added property(DSMException.cs properties) Exceptions . I went through these two solutions-
Custom exception with properties
What is the correct way to make a custom .NET Exception serializable?
I have a Property
class -DSMException which contains three properties Type,Message, InnerExceptionMessage, which needs to be dsiplayed.
DSMException.cs
public class DSMException { public string Type { get; set; } public string Message { get; set; } public string InnerExceptionMessage { get; set; } }
The Respective custom Exception class is given.
FatalException.cs
public class FatalException :Exception { DSMException exception = new DSMException(); public FatalException():base() { } public FatalException(string? Message): base(Message) { exception.Type = "FATAL"; exception.Message = "MESSAGE:" + Message; } public FatalException(string? Message,Exception ex) : base(Message,ex) { exception.Type = "FATAL"; exception.Message = "MESSAGE: " + ex.Message; exception.InnerExceptionMessage = "MORE DET: " + ex.ToInnerMostException().Message; } }
I am throwing exceptions like below code Channel.cs
public override void Run(ServiceSettings settings, DataSource dataSource, string path) { try { var channel = entities.Channels .Where(c => c.Name == parameters.Channel) .FirstOrDefault(); if (channel != null) { // ANY LOGIC } else { throw new FatalException("Invalid Channel Name !!!"); } } catch (FatalException ex)// for channel is null { throw ex; } catch (Exception ex) { throw ex; } }
The error raises here during the catching of the Exceptions-FatalExceptions
FolderInvocation.cs (Error)
private void DoFolderInvocation(DataSource dataSource, Plugin plugin) { // Do type invocation try { result = helper.Invoke(importableFile.Path);// This invokes the Run method, I skipped those codes if (result == null) logger.WriteError($"{dataSource.Key}: Unknown error while processing file '{importableFile.Path}'."); else if (result.Success == false) logger.WriteError($"{dataSource.Key}: Error while processing file '{importableFile.Path}'. {result.Message}"); else logger.WriteDebug($"{dataSource.Key}: File '{importableFile.Path}' was processed successfully. {result.Message}"); } catch (FatalException exFatal)// **Problem Arises here-> need to get Ex.Type in the FatalException** { logger.WriteError($"{dataSource.Key}: An error occurred while processing data source: {exFatal.Message}"); throw exFatal; } catch (Exception ex) { logger.WriteError($"{dataSource.Key}: Invocation error while processing file '{importableFile.Path}'. {ex.Message}"); } }
What I am missing, as far these minimum reproduced code is correct but I need to get Ex.Type in the FatalException. Kindly advice me.
If I understand you correctly, you just need to forward the fields as public properties:
public class FatalException: Exception { private readonly DSMException _exception = new DSMException(); /* ... snip ... */ public string MyType => _exception.Type; public string MyMessage => _exception.Message; public string MyInnerExceptionMessage => _exception.InnerExceptionMessage; }
It does seem to defeat the purpose of the DSMException
class a bit however. You could make the DSMException
a public property, but I’d strongly suggest to make it immutable beforehand.
I obviously don’t know the intended purpose of the DSMException
class, however since all values are assembled in the constructors anyway, you could also directly assign to public properties:
public FatalException(string? Message): base(Message) { Type = "FATAL"; Message = "MESSAGE:" + Message; } public string MyType { get ; } public string MyMessage { get ; } public string MyInnerExceptionMessage { get ; }
To continue on the immutability suggestion: You could define your DSMException
class like so:
public sealed class DSMException { public DSMException(string type, string message, string innerMessage) { Type = type; Message = message; InnerExceptionMessage = innerMessage; } public string Type { get; } public string Message { get; } public string InnerExceptionMessage { get; } }
… and then just make it a public property:
public class FatalException: Exception { /* ... snip ... */ public DSMException DSM => _exception; }
It does appear that you still have to duplicate most of the constructor code across FatalException
, ErrorException
, WarningException
etc.
Also note that as long as your custom exceptions only fly around in the same AppDomain, everything is fine; the moment they may cross domain boundaries (e.g. by wire), DSMException
needs to be serializable and the serialization methods of your custom exceptions would need to be implemented as well.