Same type exclusion from different places

Let's say you have two different libraries that you write for different file formats. One parses file type A and one parses type B. Now I see that most of the time most people say that the exceptions already defined (let's say we're using C # and .NET) are sufficient to handle most situations. In this case, I think it's okay that in both cases, if we run into some problems while parsing, we throw an InvalidDataException that tells us that the format is wrong. What happens when we need to catch both exceptions in a higher-level function that needs to do something with them?

void SomeHigherFunction()
{
    try
    {
        int x = GetSomeDataFromFileA();  // throws InvalidDataException
        int y = GetSomeDataFromFileB();  // throws InvalidDataException
    }
    catch(InvalidDataException)   // what failed ? 
    {
         ShowMessageWithWhatFileFailed()  // what display ?
    }
}

      

How do we know where the code failed to execute? Should there be two different types of exception in this case, one TypeAException and one TypeBException, or something lightweight here that I missed? I don't want to wrap every function and return a bool with the result. In this case, I would wrap function A in a function and let it return true if successful and execute B further. But this is clearly bad design and misuse of exceptions. Should I just create new types in these cases? Or how?

+3


source to share


1 answer


You can use Exception.Data Collection to pass the owner of the Exception and do something with it.

I have processed your example a bit, but I think this suits your requirements:



class Program
{
    [Serializable]
    public abstract class Parser
    {
        public int GetData()
        {
            bool error = true;
            if (error)
            {
                InvalidDataException exception = new InvalidDataException();
                exception.Data.Add("owner", this);
                throw exception;
            }
            return 0;
        }

        public abstract void handleError();
    }
    [Serializable]
    private class ParserA : Parser
    {
        public override void handleError()
        {
            Console.WriteLine("Handled in A");
        }
    }
    [Serializable]
    private class ParserB : Parser
    {
        public override void handleError()
        {
            Console.WriteLine("Handled in B");
        }
    }
    static void Main(String[] args)
    {
        try
        {
            int x = new ParserA().GetData();
            int y = new ParserB().GetData();
        }
        catch (InvalidDataException ex)
        {
            Parser parser = ex.Data["owner"] as Parser;
            if(parser != null)
                parser.handleError();

            // or even this if you prefer:
            if (parser is ParserA)
                Console.WriteLine("A");
        }
    }
}

      

In a real case, the GetData method will be virtual, but you got the idea

0


source







All Articles