Inheriting from Grain<T> gives confusing exception
- 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
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