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

Proposal: catch and add better exceptions in ModelBuilder. #13076

Open
NickCraver opened this issue Aug 22, 2018 · 3 comments
Open

Proposal: catch and add better exceptions in ModelBuilder. #13076

NickCraver opened this issue Aug 22, 2018 · 3 comments

Comments

@NickCraver
Copy link
Member

NickCraver commented Aug 22, 2018

I'm doing a port of a Linq2SQL code base over to Entity Framework Core and approaching this largely as a new user to EF Core. On the first app launch after getting things compiling again, I'm getting exceptions with my model that look like this:

image

Text version:

Exception message: Value cannot be null.
Stack trace:
[ArgumentNullException: Value cannot be null.
Parameter name: type]
   System.Reflection.IntrospectionExtensions.GetTypeInfo(Type type) +14543064
   Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.InversePropertyAttributeConvention.ConfigureInverseNavigation(InternalEntityTypeBuilder entityTypeBuilder, MemberInfo navigationMemberInfo, InternalEntityTypeBuilder targetEntityTypeBuilder, InversePropertyAttribute attribute) +315
   Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.InversePropertyAttributeConvention.Apply(InternalEntityTypeBuilder entityTypeBuilder, PropertyInfo navigationPropertyInfo, Type targetClrType, InversePropertyAttribute attribute) +258
   Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.NavigationAttributeEntityTypeConvention`1.Apply(InternalEntityTypeBuilder entityTypeBuilder) +713
   Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ImmediateConventionScope.OnEntityTypeAdded(InternalEntityTypeBuilder entityTypeBuilder) +170
   Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.RunVisitor.VisitOnEntityTypeAdded(OnEntityTypeAddedNode node) +26
   Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionVisitor.VisitConventionScope(ConventionScope node) +142
   Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionVisitor.VisitConventionScope(ConventionScope node) +142
   Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionVisitor.VisitConventionScope(ConventionScope node) +142
   Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionBatch.Run() +221
   Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionBatch.Dispose() +15
   Microsoft.EntityFrameworkCore.Metadata.Internal.InternalModelBuilder.Entity(TypeIdentity& type, ConfigurationSource configurationSource, Boolean throwOnQuery) +2550
   Microsoft.EntityFrameworkCore.Metadata.Internal.InternalModelBuilder.Entity(Type type, ConfigurationSource configurationSource, Boolean throwOnQuery) +91
   Microsoft.EntityFrameworkCore.ModelBuilder.Entity(Type type) +105
   Microsoft.EntityFrameworkCore.Infrastructure.ModelCustomizer.FindSets(ModelBuilder modelBuilder, DbContext context) +182
   Microsoft.EntityFrameworkCore.Infrastructure.RelationalModelCustomizer.FindSets(ModelBuilder modelBuilder, DbContext context) +68
   Microsoft.EntityFrameworkCore.Infrastructure.RelationalModelCustomizer.Customize(ModelBuilder modelBuilder, DbContext context) +54
   Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.CreateModel(DbContext context, IConventionSetBuilder conventionSetBuilder, IModelValidator validator) +236
   System.Lazy`1.CreateValue() +236
   System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() +31
   System.Lazy`1.get_Value() +14621129
   Microsoft.EntityFrameworkCore.Internal.DbContextServices.CreateModel() +222
   Microsoft.EntityFrameworkCore.Internal.DbContextServices.get_Model() +66
   lambda_method(Closure , ServiceProviderEngineScope ) +3137
   Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType) +100
   Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider) +51
   Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies() +52
   Microsoft.EntityFrameworkCore.DbContext.get_InternalServiceProvider() +409
   Microsoft.EntityFrameworkCore.RelationalDatabaseFacadeExtensions.GetRelationalService(IInfrastructure`1 databaseFacade) +66
   Microsoft.EntityFrameworkCore.RelationalDatabaseFacadeExtensions.SetCommandTimeout(DatabaseFacade databaseFacade, TimeSpan timeout) +127
   StackOverflow.Models.DBContext..ctor(DbConnection connection) in C:\code\stackoverflow\StackOverflow\Models\DataContexts\DBContext.cs:44

Further technical details

EF Core version: 2.1.2

My setup details aren't important, the issue here is the exception. What went wrong? All I can do is go check everything in every class on the model and hope it's right. In that stack we have useful info though. For example, Microsoft.EntityFrameworkCore.ModelBuilder.Entity(Type type) has the type we're building.

Proposal:

Could we catch exceptions in ModelBuilder.Entity(Type type) and wrap them (current exception being the .InnerException), outputting a much more useful error/message to the user? For example today I get:

Value cannot be null.

What if instead it said:

There was an error building the model with type 'StackOverflow.Models.Post': Value cannot be null.

We could get much more detailed, catching exceptions further up in the visitor and actually providing member information as well, laying out the exact type and member that had an issue. But even the type would be helpful as a quick improvement.

Thoughts?

@ajcvickers
Copy link
Member

@NickCraver Could you file a new issue with a repro for the ArgumentNullException, since we would like to fix this.

For the idea here, we think it could be potential, but due to way conventions run it could be difficult to give valid and useful additional information.

@AndriySvyryd
Copy link
Member

We would need #15898 to do this

@conficient
Copy link

Just run into a similar issue with this on .NET 5 / EF Core 5.x - getting NullReferenceException on ConfigureInverseNavigation. Was driving me nuts that I had no information in the stack trace that pointed at the issue!

I just tried updating the EF packages to .NET 6 (preview) and tried again. This time we get more usable information:

Message: 
    Test method TestContext.AnvilFGDEV_Test.ReadTablesAsync threw exception: 
    System.Collections.Generic.KeyNotFoundException: The given key 'System.Nullable`1[System.Decimal] CPSChargePartner' was not present in the dictionary.

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

No branches or pull requests

4 participants