0

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.

Sarath Mohandas
  • 360
  • 5
  • 20

1 Answers1

1

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.

sunside
  • 7,545
  • 8
  • 47
  • 71
  • There are four other types of User Defined Exceptions -namely FatalException, InfoException, WarningException,ErrorException. I created DSMExceptions.cs to handle these four types of exceptions with reduced code. – Sarath Mohandas Jul 10 '20 at 10:54
  • Updated my answer. – sunside Jul 10 '20 at 11:07
  • Would you mind to edit my code ? since there is some errors during initializing part of FatalExceptions.cs. – Sarath Mohandas Jul 10 '20 at 11:55
  • It wouldn't be much of a question if it had code working as expected. :)) Could you add some details about the errors you're observing (to your question)? – sunside Jul 10 '20 at 12:05