Convex.Client.Analyzer
0.3.1
Bundled into Convex.Client. Install the main package instead.
dotnet add package Convex.Client.Analyzer --version 0.3.1
NuGet\Install-Package Convex.Client.Analyzer -Version 0.3.1
<PackageReference Include="Convex.Client.Analyzer" Version="0.3.1" />
<PackageVersion Include="Convex.Client.Analyzer" Version="0.3.1" />
<PackageReference Include="Convex.Client.Analyzer" />
paket add Convex.Client.Analyzer --version 0.3.1
#r "nuget: Convex.Client.Analyzer, 0.3.1"
#:package Convex.Client.Analyzer@0.3.1
#addin nuget:?package=Convex.Client.Analyzer&version=0.3.1
#tool nuget:?package=Convex.Client.Analyzer&version=0.3.1
Convex .NET Client Analyzer
Roslyn analyzers for the Convex .NET Client library. Provides compile-time analysis to enforce best practices, prevent common issues, and suggest performance optimizations.
Installation
Install the analyzer NuGet package:
dotnet add package Convex.Client.Analyzer
The analyzer will automatically run during compilation and provide warnings for code that violates the rules.
Rules
CVX001: Avoid direct IConvexClient method calls
Severity: Warning
Direct calls to IConvexClient methods bypass error handling, retry logic, and performance optimizations provided by extension methods.
Example:
// ❌ Avoid
var result = client.Query<object>("functions/getData");
// ✅ Prefer
var result = await client.Query<object>("functions/getData").WithArgs(args).ExecuteAsync();
CVX002: Ensure connection state monitoring for real-time features
Severity: Warning
Real-time subscriptions can fail silently when the connection is lost. Monitor connection state to handle disconnections gracefully.
Example:
// ❌ Avoid
var subscription = client.Observe<Data>("functions/getData");
// ✅ Prefer
var subscription = client.CreateResilientSubscription<Data>("functions/getData");
// Or
client.ConnectionStateChanges.Subscribe(state => { /* handle state */ });
var subscription = client.Observe<Data>("functions/getData");
CVX003: Avoid generic Exception types in Convex operations
Severity: Warning
Generic exception handling makes error diagnosis difficult and can hide Convex-specific issues. Use specific Convex exception types for better error handling.
Example:
// ❌ Avoid
try
{
await client.Query<object>("functions/getData").ExecuteAsync();
}
catch (Exception ex)
{
// Too generic
}
// ✅ Prefer
try
{
await client.Query<object>("functions/getData").ExecuteAsync();
}
catch (ConvexFunctionException ex)
{
// Handle function errors
}
catch (ConvexNetworkException ex)
{
// Handle network errors
}
catch (ConvexException ex)
{
// Handle other Convex errors
}
CVX004: Use type-safe function name constants
Severity: Warning
String literals for function names are error-prone and prevent compile-time validation. Use the generated ConvexFunctions constants for type safety.
Example:
// ❌ Avoid
var result = await client.Query<object>("functions/getMessages").ExecuteAsync();
// ✅ Prefer
var result = await client.Query<object>(ConvexFunctions.Queries.GetMessages).ExecuteAsync();
CVX005: Missing error handling in async operations
Severity: Info
Unhandled async Convex operations can hide errors. Add error handling with try-catch or OnError() handlers.
Example:
// ❌ Avoid
var result = await client.Query<object>("functions/getData").ExecuteAsync();
// ✅ Prefer
try
{
var result = await client.Query<object>("functions/getData").ExecuteAsync();
}
catch (ConvexException ex)
{
// Handle error
}
// Or use OnError handler
await client.Query<object>("functions/getData")
.OnError(ex => { /* handle error */ })
.ExecuteAsync();
CVX006: Subscription disposal
Severity: Warning
Subscriptions that are not properly disposed can cause memory leaks. Implement IDisposable pattern for classes with subscriptions.
Example:
// ❌ Avoid
class MyClass
{
private IDisposable? _subscription;
public void Start()
{
_subscription = client.Observe<Data>("functions/getData").Subscribe(/* ... */);
}
// Missing Dispose()
}
// ✅ Prefer
class MyClass : IDisposable
{
private IDisposable? _subscription;
public void Start()
{
_subscription = client.Observe<Data>("functions/getData").Subscribe(/* ... */);
}
public void Dispose()
{
_subscription?.Dispose();
}
}
CVX007: Builder pattern best practices
Severity: Warning
Builder pattern issues: missing ExecuteAsync(), invalid chaining, or missing required methods.
Example:
// ❌ Avoid
var builder = client.Query<object>("functions/getData");
// Missing ExecuteAsync()
// ✅ Prefer
var result = await client.Query<object>("functions/getData").ExecuteAsync();
CVX008: Type safety for function arguments
Severity: Info
Anonymous objects for arguments reduce type safety. Use typed argument classes when available.
Example:
// ❌ Avoid
var result = await client.Query<object>("functions/getData")
.WithArgs(new { id = 123, name = "test" })
.ExecuteAsync();
// ✅ Prefer
class GetDataArgs
{
public int Id { get; set; }
public string Name { get; set; }
}
var result = await client.Query<object>("functions/getData")
.WithArgs(new GetDataArgs { Id = 123, Name = "test" })
.ExecuteAsync();
CVX009: Optimistic update best practices
Severity: Info
Optimistic update issues: missing rollback handlers, optimistic updates on queries, or missing optimistic updates on mutations.
Example:
// ❌ Avoid - optimistic update on query
await client.Query<object>("functions/getData")
.OptimisticWithAutoRollback(/* ... */)
.ExecuteAsync();
// ✅ Prefer - optimistic update on mutation with rollback
await client.Mutate<object>("functions/updateData")
.OptimisticWithAutoRollback(
optimisticUpdate: state => { /* update */ },
rollback: state => { /* rollback */ })
.ExecuteAsync();
CVX010: Cache invalidation patterns
Severity: Info
Mutations that modify data should invalidate related queries to ensure cache consistency.
Example:
// ❌ Missing cache invalidation
await client.Mutate<object>("functions/createTodo").ExecuteAsync();
// ✅ Prefer
// Set up cache dependencies
client.DefineQueryDependency("functions/createTodo", "functions/listTodos", "functions/getTodoCount");
await client.Mutate<object>("functions/createTodo").ExecuteAsync();
Configuration
You can configure analyzer rules in your .editorconfig file:
# Disable a specific rule
dotnet_diagnostic.CVX001.severity = none
# Change severity
dotnet_diagnostic.CVX005.severity = warning
# Enable as error
dotnet_diagnostic.CVX003.severity = error
Code Fixes
The analyzer package includes automatic code fixes for many rules. Use the lightbulb (Ctrl+.) in your IDE to apply fixes automatically.
Troubleshooting
Analyzers not running
- Ensure the
Convex.Client.Analyzerpackage is installed - Restart your IDE
- Run
dotnet clean && dotnet build
False positives
If you encounter false positives, you can:
- Suppress the warning with
#pragma warning disable CVX### - Configure the rule severity in
.editorconfig - Report the issue on GitHub
Contributing
Contributions are welcome! Please see the main repository for contribution guidelines.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|
Initial release (0.0.1) of Roslyn analyzers for Convex .NET Client. Includes rules for client usage patterns, error handling, performance optimizations, and security validation. See CHANGELOG.md for full details.