0

As I get it, since the Exception is thrown in the parent, the message is as it is defined in parent - null (System.Exception: "Exception_WasThrown", message: "Exception of type 'System.Exception' was thrown."). How to work around this issue?

Program, roughly:

internal abstract class Figure
    {
        protected string BadFigExceptionMessage { get; set; }
        public Figure(params int[] measurements)
        {
            if (measurements.Any(x => x<=0)) throw new Exception(BadFigExceptionMessage);
        }
    }

    class Triangle : Figure
    {
        public Triangle(params int[] sides) : base(sides) 
        { 
            BadFigExceptionMessage = "Such a triangle does not exist."; 
        }
    }

My test with NUnit:

    [Test]
    [TestCase(-2, -2, -6)]
    [TestCase(0, 0, 0)]
    public void CalculateSquareOf_ImpossibleTriagSides_ReturnExceptionNoSuchTriag(int a, int b, int c)
    {
        Exception ex = Assert.Throws<Exception>(() => 
SquareCalculatorLib.Calculator.CalculateSquareOf(a, b, c)); //involves the Triangle constructor
        Assert.That(ex.Message, Is.EqualTo("Such a triangle does not exist."));
    }
YoNa
  • 19
  • 7
  • Does this answer your question? [How to catch exception from a constructor in a derived class with C#?](https://stackoverflow.com/questions/17266105/how-to-catch-exception-from-a-constructor-in-a-derived-class-with-c) – McNets Apr 30 '22 at 18:16
  • @McNets not quite. I need to throw exception with a particular message which differes from child to child. But it is always thrown with the message set in the parent (null) – YoNa Apr 30 '22 at 18:40
  • @McNets I actually just figured it's because of the constructors' execution order however I still don't know how to work around this issue other than raise 1 exception with the message "Such a figure does not exist" – YoNa Apr 30 '22 at 18:46

1 Answers1

2

Injecting the exception message into the constructor is one way to do this:

internal abstract class Figure
{
    public Figure(string exMsg, params int[] measurements)
    {

        if (measurements.Any(x => x <= 0)) throw new Exception(exMsg);
    }
}

class Triangle : Figure
{
    public Triangle(int a, int b, int c) : base("Such a triangle does not exist.", a, b ,c) { }
}
jwdonahue
  • 6,199
  • 2
  • 21
  • 43
  • It worked except the parameters should be reversed! Is it a good practice though if it looks like `public Figure(string exMsg = "Bad Figure", params int[] measurements)` and then I call `Triangle triangle = new Triangle(0, 0, 0);` ? – YoNa Apr 30 '22 at 18:56
  • 2
    Personally I would define the error message as `virtual` in the `Figure` class and override it in the `Triangle` class in order not to pass it as a parameter - https://dotnetfiddle.net/MreQXn - but everyone has a different opinion about what is 'good practice'. – stuartd Apr 30 '22 at 19:50
  • 1
    Doh! I barely read the code and missed the params... – jwdonahue Apr 30 '22 at 20:56
  • 1
    @YoNa, it's fine. You could have several constructors, including a default constructor that each initialize the base class in different ways if you wanted. – jwdonahue Apr 30 '22 at 21:09
  • 1
    I answered your question without addressing other important issues wrt to you code however. Most important, triangles always have 3 sides and your code allows for them to have 1 or more. You'd probably want to make that `Triangle(int a, int b, int c) base("Such a triangle does not exist.", a, b, c). – jwdonahue Apr 30 '22 at 21:14