Skip to content

Make missing Chronicle setup obvious: analyzer, runtime error, and docs#2322

Merged
woksin merged 7 commits into
mainfrom
feat/chronicle-setup-diagnostics
Jul 4, 2026
Merged

Make missing Chronicle setup obvious: analyzer, runtime error, and docs#2322
woksin merged 7 commits into
mainfrom
feat/chronicle-setup-diagnostics

Conversation

@woksin

@woksin woksin commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Summary

Setting up Arc without wiring Chronicle is a valid choice (commands and queries can run over MongoDB or EF Core). But if you do use Chronicle, forgetting WithChronicle() used to surface as a cryptic container error at first use. This PR makes that mistake obvious across three layers — a compile-time analyzer, an actionable runtime error, and clearer docs and API reference.

Added

  • New ARCCHR0005 analyzer that warns at compile time when a project sets up Arc with AddCratisArc but never calls WithChronicle() or AddCratis(), yet uses Chronicle in the same project (an aggregate root, reactor, reducer, projection, [EventType] event, or a type injecting IEventLog/IEventStore). It stays silent when Chronicle genuinely is not used.

Changed

  • Resolving a Chronicle service such as IEventLog without Chronicle configured now throws an actionable error that names the command, query, or validator and its parameter, and points at the fix (WithChronicle() or AddCratis()) instead of a raw "Unable to resolve service for type EventStoreName" container exception.
  • Expanded the IntelliSense/API documentation on AddCratis, UseCratis, AddCratisArc, UseCratisArc, and WithChronicle (all overloads): they clarify that the application hosts the Chronicle client — which connects to a separately running Chronicle instance — rather than an embedded engine, and include runnable examples for the common setups.

woksin and others added 4 commits July 3, 2026 23:32
When AddCratisArc is used without WithChronicle, a command, provide method,
validator, or query that depends on a Chronicle service such as IEventLog
failed with a raw container exception ("Unable to resolve service for type
EventStoreName...") that read like a framework bug.

Translate the container's activation failure into CannotResolveDependency,
which names the member and parameter, preserves the original failure as the
inner exception, and appends a hint to call WithChronicle()/AddCratis() when
the failure involves a Chronicle type. Covers command Handle/Provide and
validators via ParameterDependencyResolver, and query performer dependencies.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Warn at compile time when a project sets up Arc with AddCratisArc but never
calls WithChronicle() or AddCratis(), yet uses Chronicle in the same project:
an aggregate root, reactor, reducer, projection, [EventType] event, or a type
injecting IEventLog/IEventStore.

Running Arc without Chronicle stays a valid, supported setup, so the rule is
silent unless Chronicle is actually used, and it reports only within a single
compilation so multi-project host setups never false-positive.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Expand the XML docs on AddCratis, UseCratis, AddCratisArc, UseCratisArc and
WithChronicle across their overloads: clarify that the app hosts the Chronicle
client rather than the engine, how the pieces compose, and the isolated setups.
Add runnable <example> blocks to the AddCratis, AddCratisArc and WithChronicle
decision points so the wiring shows up in IntelliSense.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Clarify in the Cratis package guide that AddCratis wires the Chronicle client
against a separately running instance (the cratis/chronicle container) rather
than an embedded engine, and add a "Running Arc or Chronicle on their own"
section. Add the ARCCHR0005 rule page and wire it into the code-analysis nav.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@woksin woksin added the minor label Jul 3, 2026
Comment on lines +105 to +116
foreach (var type in GetAllTypes(compilation.Assembly.GlobalNamespace))
{
if (IsAggregateRoot(type) ||
ImplementsMarker(type, ReactorInterfaceName, ReactorsNamespace) ||
ImplementsMarker(type, ReducerInterfaceName, ReducersNamespace) ||
HasEventTypeAttribute(type, eventTypeAttribute) ||
IsProjection(type, projectionForType) ||
InjectsChronicleService(type))
{
return type.Name;
}
}
@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown

NuGet packages for this PR, e.g. Cratis.Arc:
https://github.com/cratis/arc/packages/1655206?version=20.48.5

woksin and others added 3 commits July 4, 2026 00:11
The message ended with "See the inner exception for details", which is a
dead end once the exception is flattened into CommandResult.ExceptionMessages
(strings only, no inner exception). Inline the underlying failure message so
the actionable detail survives flattening.

This keeps the .NET activation guidance visible for a missing validator
dependency, which a Chronicle.Specs command scenario asserts on.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Broaden the ARCCHR0005 analyzer from a fixed set of markers to any interface,
attribute (on a type or its properties), or injected service interface in the
Cratis.Chronicle namespace. This adds model-bound projections ([FromEvent],
[SetFrom], [SetValue], ...) and covers new Chronicle features automatically,
while aggregate roots (a Cratis.Arc.Chronicle base type) stay matched directly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A reader interpreted "What AddCratis sets up for you" as running Chronicle
in-process. Lead the bullet with "a client, not the engine", add a
two-process topology diagram (app + Chronicle client -> separate Chronicle
server), and correct the earlier "event store" wording to "event store
client" so the deployment model is unmistakable.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@woksin woksin merged commit dc1571c into main Jul 4, 2026
12 of 52 checks passed
@woksin woksin deleted the feat/chronicle-setup-diagnostics branch July 4, 2026 06:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant