Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

{"message":"Internal server error"} #193

Closed
DotNetRockStar opened this issue Feb 17, 2015 · 12 comments
Closed

{"message":"Internal server error"} #193

DotNetRockStar opened this issue Feb 17, 2015 · 12 comments

Comments

@DotNetRockStar
Copy link

I pulled the nuget package down (Swashbuckle) on a brand new sample application and ran the project with no problems. /swagger/docs/v1 worked perfectly.
I pulled the nuget package down (Swashbuckle) on a large existing application I have (same version of Web Api and Swashbuckle) and I get this when I do a GET /swagger/docs/v1

{"message":"Internal server error"}

:*(
How might I troubleshoot something like this?

@domaindrivendev
Copy link
Owner

Hmmm that's not good. Could I ask you to dig a little deeper on the troubleshooting and help me get this resolved?

Not sure why you're getting such a vague error - actually looks like it might be iis returning this and not your application. Do you have any kind of global setup for unhandled exceptions?

If you can't get to the root exception you could clone the repo and build from source (use build.bat). Then drop a breakpoint into SwggerDocsHandler.

Your help would be much appreciated

Thanks

@DotNetRockStar
Copy link
Author

When I get a little bit of time I can certainly take a look. Unfortunately it is a work solution so it may take a bit of time to dig in and determine. I'll post back when I have pulled down the solution and identified what the problem is.

@DotNetRockStar
Copy link
Author

I got a chance to get in the code only to find out that it was my teams DelegatingHandler throwing the error. After I fixed it I got a new error though. Not sure if this deserves a new thread but I will post the new exception here. I think I understand the exception that is being thrown but I am hoping there is a way around this because I am not sure I want to go modifying my application code to make this work.

"This exception is based on actual events. Names have been changed to protect the innocent. lolz".
== Exception ==
System.NotSupportedException: Not supported by Swagger 2.0: Multiple operations with path 'api/v1/accounts' and method 'GET'. See the config setting - "ResolveConflictingActions" for a potential workaround
at Swashbuckle.Swagger.SwaggerGeneratorOptions.DefaultConflictingActionsResolver(IEnumerable1 apiDescriptions) at Swashbuckle.Swagger.SwaggerGenerator.CreatePathItem(IEnumerable1 apiDescriptions, SchemaRegistry schemaRegistry)
at Swashbuckle.Swagger.SwaggerGenerator.<>c__DisplayClass7.b__4(IGrouping2 group) at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable1 source, Func2 keySelector, Func2 elementSelector, IEqualityComparer1 comparer) at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable1 source, Func2 keySelector, Func2 elementSelector)
at Swashbuckle.Swagger.SwaggerGenerator.GetSwagger(String rootUrl, String apiVersion)
at Swashbuckle.Application.SwaggerDocsHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpMessageInvoker.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Web.Http.Dispatcher.HttpRoutingDispatcher.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.DelegatingHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at [MY APPLICATION].Handlers.[Whatever]Handler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) in[Whatever Handler .cs: line xxx]

@domaindrivendev
Copy link
Owner

See issue #142 for a full discussion

Bottom line is that the Swagger 2.0 spec does not allow URI's that differ only in query component to be described as separate operations.

As Swagger is just a HTTP/REST description language and is agnostic of implementation, there is nothing stopping you from routing to different actions based off query string only but you just can't describe them as separate actions. If you don't want to change your impl, SB provides a kind of "merge" option to combine conflicting actions into one Operation description. See here for details https://github.com/domaindrivendev/Swashbuckle#working-around-swagger-20-constraints

@DotNetRockStar
Copy link
Author

This is just Odd to me. I have not pulled down the code but multiple operations should not be an issue if you are using the api description functionality provided to parse the services. It makes me think that perhaps you are pulling routes from the route tabe and manually finding the method and scanning that way... oh well. I might look into this merge functionality. If that doesn't work I suppose I'll have to use built in documentation.

Thanks.

@domaindrivendev
Copy link
Owner

Nope - I'm not doing any manual discovery of routes. Every Swagger Operation is built from a corresponding ApiDescription that is provided by WebApi's built-in metadata layer - ApiExplorer.

If you have a different controller action for each of the following routes:

/api/customers
/api/customers?type=premium

The ApiExplorer will have a corresponding ApiDescription for each one

However, Swagger Operations are identified by path only (e.g. sans query string) and so you can't have an Operation for each of these. Hence the resolver.

Trust me, this is a Swagger constraint independent of SB!

@DotNetRockStar
Copy link
Author

Ha... interesting. I always thought it would be the same descriptor. I'll have to check that out. Thanks for the reply.

@DotNetRockStar
Copy link
Author

I see why you did what you did. Have you considered making some assumptions and attempting to "merge" the 2 methods into a single node at "swagger generation time"?
For example:
Method A: GET /products
Method B: GET /products?x={x}

While parsing you can quickly determine that these two are attempting to represent the same logical resource (i.e. GET /products). If you make sure that the return type is the same (which it should be. If its not the user is holding it wrong) then you can make educated guesses and "auto-merge" the N number of methods into a single node.
example:
Method A: GET /products
Method B: GET /products?x={x}
Translates to
Node: GET /products?x={x}

  • Parameters
    -- x, optional, type=(whatever), etc...
  • returns
    -- (whatever).

I hope this makes sense.

@DotNetRockStar
Copy link
Author

I may be simply repeating what is in another thread (even the one you linked me). I admit I did not read the thread you linked. Just tell me to go read the link if this is what you are already doing :)

@domaindrivendev
Copy link
Owner

Totally makes sense and it is something I've considered - it's just lower on the list of priorities so for now, I've left it up to the API author. When it comes to auto-generating an API description from static code constructs, I've found that assumptions rarely pay off :)

@domaindrivendev
Copy link
Owner

With that said though, I guess you're situation provides an ideal opportunity to implement a generic "merge" strategy and try it out using the existing config. option. Why not give it a whirl and if it works well for you it could be a good addition in the box.

@DotNetRockStar
Copy link
Author

Cool. I may pull the code down and take a look. Thanks again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants