aspnetcore icon indicating copy to clipboard operation
aspnetcore copied to clipboard

ApiDescriptionGroupCollectionProvider fails for controllers with parameter type Exception

Open gkeongit opened this issue 5 years ago • 7 comments

Description of the bug

If a controller method uses a parameter of type System.Exception, accessing Microsoft.AspNetCore.Mvc.ApiExplorer.ApiDescriptionGroupCollectionProvider.ApiDescriptionGroups allocates GBs of memory and seems to be in an infinite loop.

The same happens, if not the controller parameter itself, but one of its direct or nested properties is of type System.Exception.

To Reproduce

Write a controller with an action that takes a System.Exception as parameter:

[Route("[controller]/[action]")]
[ApiExplorerSettings(IgnoreApi = false, GroupName = nameof(TroublesController))]
public class TroublesController : Controller
{
	public IActionResult TroublesMethod(Exception parameter)
	{
		return View();
	}
}

Write a controller that displays a view to show the API description:


public class HomeController : Controller
{
	public IActionResult Index(
                [FromServices]  IApiDescriptionGroupCollectionProvider apiExplorer) 
                        => View(apiExplorer);
}

In the view that should display the API, access the ApiDescriptionGroups:


@using Microsoft.AspNetCore.Mvc.ApiExplorer;
@model IApiDescriptionGroupCollectionProvider

// This will not return and consume lots of memory
@Model.ApiDescriptionGroups.Version
        

Further technical details

ASP.NET Core Version:

ASP.NET Core 3.1

Output of dotnet --info:

.NET Core SDK (reflecting any global.json): Version: 3.1.101 Commit: b377529961

Runtime Environment: OS Name: Windows OS Version: 10.0.17763 OS Platform: Windows RID: win10-x64 Base Path: C:\Program Files\dotnet\sdk\3.1.101\

Host (useful for support): Version: 3.1.1 Commit: a1388f194c

.NET Core SDKs installed: 2.1.802 [C:\Program Files\dotnet\sdk] 3.1.101 [C:\Program Files\dotnet\sdk]

.NET Core runtimes installed: Microsoft.AspNetCore.All 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.All 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.All 2.1.15 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.All 2.2.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.App 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 2.1.15 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 2.2.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 3.0.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 3.1.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.NETCore.App 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 2.1.15 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 2.2.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 3.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 3.1.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.WindowsDesktop.App 3.1.1 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

To install additional .NET Core runtimes or SDKs: https://aka.ms/dotnet-download

IDE:

Microsoft Visual Studio Professional 2019 Version 16.4.5

gkeongit avatar Feb 18 '20 13:02 gkeongit

Thanks for contacting us. It's not clear what you're trying to do. Do you intend to expose an API which accepts an Exception type? If not, you can apply the [NonAction] attribute on that method.

mkArtakMSFT avatar Feb 18 '20 17:02 mkArtakMSFT

Whether or not it's a mistake, this sounds like an infinite loop in the API explorer code. These kinds of bugs are really hard for users to understand the cause of.

rynowak avatar Feb 20 '20 06:02 rynowak

I don't know, why my initial response by eMail did not show up here. I paste it instead:

Thank you for your hint about the NonAction attribute. In my specific case the API accepts a type that contains a property of a type that again has a property of type Exception. But I already analyzed, that this has the same effect as using the Exception type directly in the API. So I simplified the example, which may indeed look a little bit weird now.

gkeongit avatar Feb 20 '20 07:02 gkeongit

Thanks for the details, @gkeongit. I understand it's easy in some cases to add a property on a model and expect it to be available to the server/client, but it's not optimal unless you control the serialization yourself.

mkArtakMSFT avatar Feb 26 '20 16:02 mkArtakMSFT

@mkArtakMSFT, maybe you are right about best practices for controller models. But the issue is more about some invalid behavior in the API explorer.

If the API explorer cannot handle certain kind of models (like those with an Exception as property type), it could propagate this by e.g. throwing a NotSupportedException. But it must not go into something, that looks like an endless loop eating up all available memory resources.

gkeongit avatar Feb 27 '20 10:02 gkeongit

@gkeongit I agree with you completely. This is definitely not the desired behavior. The only argument I'm making here is that this is pretty corner-case scenario, given the approach is uncommon. Because of that I've moved it to Backlog to see how many people are impacted with this. If it turns out that many are impacted, we'll prioritize this investigation. For now, I just recommend changing your model to avoid this pattern.

mkArtakMSFT avatar Feb 28 '20 06:02 mkArtakMSFT

OK, I can't change that model, so I will have to go without the API Explorer then.

gkeongit avatar Mar 02 '20 10:03 gkeongit