Mathieu VIALES
Mathieu VIALES

Reputation: 4772

Why does IIS give a broad "502.3 - Bad Gateway" error on circular constructors

I do understand why the code cant work. I don't understand what technical reasons makes it so we don't get a more explicit error message.

While developing a netcore2 app I ended up making a circular reference with constructors. I mean that the constructor of an class A instantiated an other object of type B that would itself instantiate an object of type A and so on.

Here is a simple code snippet to reproduce the circular instantiation which throws a StackOverflowException on the online compiler I made that example on.

public class A
{
    public A()
    {
        var b = new B();
    }
}

public class B
{
    public B()
    {
        var b = new B();
    }
}

public class Program
{
    public static void Main(string[] args)
    {
        var a = new A();
    }
}

Surprisingly, instead of a stackoverflow exception it is a 502.3 - Bad Gateway error that IIS gives me right before the application crashes, which doesn't give much information about the underlying problem. I expected a circular call like this to be a pattern easy enough to detect for it to be not only caught by a compiler, but even pin-pointed by VisualStudio 2017 or Resharper ultimate but nothing warned me about it.

this article as well as this one seem to indicate that the problem could be a time-out but it seems unlikely since the application crashes in under two seconds.

I simply don't understand why there is no CircularConstructionException - this sounds easy enough to implement and even worse, why isn't IIS throwing a regular StackOverflowException like the online compiler ?

Upvotes: 2

Views: 3536

Answers (3)

Matthew Steven Monkan
Matthew Steven Monkan

Reputation: 9160

I believe the correct answer is that it is a design decision of C#. Whereas other exceptions are caught and wrapped in an exception page in your case, a StackOverflowException causes the process to terminate, which is reason to report a 502.3 response (reporting a connection failure).


From the MSDN page on StackOverflowExceptions:

In prior versions of the .NET Framework, your application could catch a StackOverflowException object (for example, to recover from unbounded recursion). However, that practice is currently discouraged because significant additional code is required to reliably catch a stack overflow exception and continue program execution.

Starting with the .NET Framework version 2.0, a StackOverflowException object cannot be caught by a try-catch block and the corresponding process is terminated by default. Consequently, users are advised to write their code to detect and prevent a stack overflow. For example, if your application depends on recursion, use a counter or a state condition to terminate the recursive loop. Note that an application that hosts the common language runtime (CLR) can specify that the CLR unload the application domain where the stack overflow exception occurs and let the corresponding process continue. For more information, see ICLRPolicyManager Interface and Hosting the Common Language Runtime.

Upvotes: 3

Jimmy
Jimmy

Reputation: 28406

I simply don't understand why there is no CircularConstructionException - this sounds easy enough to implement

There's nothing illegal at runtime about an object instantiating another object, even of the same type. The issue is that you haven't controlled the stack properly, so a StackOverflowException is actually appropriate. In this case, arguably the issue could be detected by the compiler, but that's still not a runtime exception.

and even worse, why isn't IIS throwing a regular StackOverflowException like the online compiler ?

IIS probably doesn't know why it died. It creates a worker process to run your app; that process died due to the stack overflow. The IIS host process then returned an error indicating that the worker process failed. Maybe "Bad Gateway" isn't the most clear, but the IIS host doesn't know anything about the stack overflow. It just knows that its worker process is not responding or dead.

Upvotes: 2

olpro123
olpro123

Reputation: 37

This class calling itsef infinitive time and causing stack overflow

public class B
{
    public B()
    {
        var b = new B();
    }
}

Upvotes: -1

Related Questions