Repository navigation
Detect circular self-resolution instead of StackOverflowError - #423
escamoteur merged 2 commits into
Conversation
Fail fast with a StateError when a factory re-enters the same registration (e.g. registerLazySingleton<Iface>(getIt.call)), and only interpolate the catch stack when debug output is enabled.
Clear the creation-in-progress guard when the factory returns its Future, not when that Future completes, so overlapping always-new/cached async resolutions are not treated as circular self-resolution.
|
Follow-up: fixed a Bugbot finding where overlapping |
Throws a descriptive StateError instead of a StackOverflowError when a factory re-enters get<T>() for the same registration (e.g. registerLazySingleton<Iface>(getIt.call)). Plain factories are not guarded since recursive factories are legitimate. Based on #423 by @muhammadkamel.
|
Thanks a lot for this, and sorry for the long silence — the flutter_it packages weren't maintained for a few months. Merged for 9.3.0 with two tweaks: the guard now only covers lazy singletons, cached factories and async singletons (plain |
Summary
registerLazySingleton<Iface>(getIt.call)/ untyped tear-offs) and throw a clearStateErrorinstead of overflowing the stack.$stackTraceinterpolation in creation-error debug logging whenGetIt.noDebugOutputis set (that path can make release crash dumps look "native").() => getIt<Impl>()).Motivation
In production, registering an untyped tear-off of
call/getas a factory for interfaceTrecursively callsget<T>()untilStackOverflowError. Some crash reporters then drown inStackTrace.toStringwork, which obscured the real DI bug.Test plan
dart test test/circular_self_resolution_test.dartdart test(full suite)() => getIt<Impl>()/ named tear-offs