dotnet / dotnet/orleans

Inheriting from Grain<T> gives confusing exception

Open
#8,635 0 comments 0 reactions 0 assignees View on GitHub
Needs: triage :mag:
Dominant language
C#
Stars
10.9k
Forks
2.1k
Avg merge
14h 42m
Merged PRs (30d)
354

Description

```cs
using Orleans.Runtime;

var builder = WebApplication.CreateBuilder(args);
builder.Host.UseOrleans(siloBuilder =>
{
siloBuilder.UseLocalhostClustering();
siloBuilder.AddMemoryGrainStorage("tests");
});
var app = builder.Build();
app.MapGet("/", (IGrainFactory grainFactory) => grainFactory.GetGrain(Guid.NewGuid()).Test());
app.Run();

interface ITestGrain : IGrainWithGuidKey { Task Test(); }
class Test { }

class TestGrain : Grain, ITestGrain
{
private readonly IPersistentState _state;

public TestGrain([PersistentState(stateName: "test", storageName: "tests")] IPersistentState state)
{
_state = state;
}

public Task Test() => Task.CompletedTask;
}
```

Hitting the `/` endpoint gives
```
Lifecycle start canceled due to errors at stage 1000
Orleans.Storage.BadProviderConfigException: No default storage provider found loading grain type TestGrain.
at Orleans.Storage.GrainStorageHelpers.ThrowMissingProviderException(Type grainType, String name) in /_/src/Orleans.Core/Providers/GrainStorageHelpers.cs:line 46
at Orleans.Storage.GrainStorageHelpers.GetGrainStorage(Type grainType, IServiceProvider services) in /_/src/Orleans.Core/Providers/GrainStorageHelpers.cs:line 28
at Orleans.Runtime.GrainRuntime.GetStorage[TGrainState](IGrainContext grainContext) in /_/src/Orleans.Runtime/Core/GrainRuntime.cs:line 82
at Orleans.Grain`1.LifecycleObserver.SetupStorage() in /_/src/Orleans.Core.Abstractions/Core/Grain.cs:line 250
at Orleans.Grain`1.LifecycleObserver.OnStart(CancellationToken cancellationToken) in /_/src/Orleans.Core.Abstractions/Core/Grain.cs:line 273
at Orleans.LifecycleSubject.g__CallOnStart|7_0(OrderedObserver observer, CancellationToken cancellationToken) in /_/src/Orleans.Core/Lifecycle/LifecycleSubject.cs:line 139
--- End of stack trace from previous location ---
at Orleans.LifecycleSubject.OnStart(CancellationToken cancellationToken) in /_/src/Orleans.Core/Lifecycle/LifecycleSubject.cs:line 118
```

Which is confusing because a storage is configured for `TestGrain`.

It's fixed by replacing `Grain` with `Grain`.
```diff
- class TestGrain : Grain, ITestGrain
+ class TestGrain : Grain, ITestGrain
```

Is it possible to detect this misconfiguration and throw a more explicit exception?

Contributor guide

Open the contributing guide

Research direction

Start with the repro and the stack-trace entry points in src/Orleans.Core/Providers/GrainStorageHelpers.cs and src/Orleans.Core.Abstractions/Core/Grain.cs. Trace how Grain selects storage compared with Grain, then add detection for this misconfiguration so the failure identifies the incorrect inheritance or missing provider configuration and verify the existing repro no longer produces the confusing exception.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
backend, distributed-systems
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.