From d30755c243a77b88c47e0a045e0e810b244a5e60 Mon Sep 17 00:00:00 2001 From: "Jeremy D. Miller" Date: Fri, 3 Jun 2022 09:26:20 -0500 Subject: [PATCH] new MartenException base class for all exception types in Marten. Closes GH-02253 --- docs/configuration/multitenancy.md | 2 +- ...ions_should_derive_from_MartenException.cs | 28 +++++++++++++++++++ .../Events/Daemon/EventFetcherException.cs | 3 +- .../Events/Daemon/ShardStartException.cs | 3 +- .../Events/Daemon/ShardStopException.cs | 3 +- .../AmbiguousDocumentTypeAliasesException.cs | 2 +- src/Marten/Exceptions/ApplyEventException.cs | 2 +- .../Exceptions/BadLinqExpressionException.cs | 2 +- src/Marten/Exceptions/ConcurrencyException.cs | 2 +- .../Exceptions/ConcurrentUpdateException.cs | 2 +- .../DefaultTenantUsageDisabledException.cs | 2 +- .../DocumentAlreadyExistsException.cs | 2 +- .../DocumentIdTypeMismatchException.cs | 2 +- .../Exceptions/EmptyEventStreamException.cs | 2 +- .../ExistingStreamIdCollisionException.cs | 2 +- ...dvanceToNextHiAttemptsExceededException.cs | 2 +- .../InvalidCompiledQueryException.cs | 2 +- .../Exceptions/InvalidDocumentException.cs | 2 +- .../Exceptions/InvalidProjectionException.cs | 2 +- .../InvalidStreamOperationException.cs | 2 +- .../InvalidUtcDateTimeUsageException.cs | 2 +- .../Exceptions/MartenCommandException.cs | 2 +- src/Marten/Exceptions/MartenException.cs | 27 ++++++++++++++++++ .../Exceptions/MartenSchemaException.cs | 2 +- .../NonExistentDocumentException.cs | 2 +- .../Exceptions/NonExistentStreamException.cs | 2 +- .../ProgressionProgressOutOfOrderException.cs | 2 +- src/Marten/Exceptions/RollbackException.cs | 2 +- .../Exceptions/StreamLockedException.cs | 2 +- .../Exceptions/UnknownEventTypeException.cs | 2 +- src/Marten/Storage/ITenancy.cs | 3 +- 31 files changed, 88 insertions(+), 29 deletions(-) create mode 100644 src/CoreTests/all_exceptions_should_derive_from_MartenException.cs create mode 100644 src/Marten/Exceptions/MartenException.cs diff --git a/docs/configuration/multitenancy.md b/docs/configuration/multitenancy.md index 0c0ec81a24..9477d4654b 100644 --- a/docs/configuration/multitenancy.md +++ b/docs/configuration/multitenancy.md @@ -144,7 +144,7 @@ public interface ITenancy : IDatabaseSource ValueTask FindOrCreateDatabase(string tenantIdOrDatabaseIdentifier); } ``` -snippet source | anchor +snippet source | anchor Assuming that we have a custom `ITenancy` model: diff --git a/src/CoreTests/all_exceptions_should_derive_from_MartenException.cs b/src/CoreTests/all_exceptions_should_derive_from_MartenException.cs new file mode 100644 index 0000000000..2c87e44eb7 --- /dev/null +++ b/src/CoreTests/all_exceptions_should_derive_from_MartenException.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Baseline; +using LamarCodeGeneration; +using Marten.Events.TestSupport; +using Marten.Exceptions; +using Shouldly; +using Xunit; + +namespace CoreTests +{ + public class all_exceptions_should_derive_from_MartenException + { + [Fact] + public void all_exceptions_types() + { + var ignoredTypes = new Type[] { typeof(ProjectionScenarioException), typeof(MartenException), typeof(FastExpressionCompiler.NotSupportedExpressionException) }; + + var exceptionTypes = typeof(MartenException).Assembly.GetTypes() + .Where(x => x.CanBeCastTo(typeof(Exception)) && !x.CanBeCastTo(typeof(MartenException)) && + !ignoredTypes.Contains(x)).ToList(); + + exceptionTypes.ShouldBeEmpty(exceptionTypes.Select(x => x.NameInCode()).Join(", ")); + + } + } +} diff --git a/src/Marten/Events/Daemon/EventFetcherException.cs b/src/Marten/Events/Daemon/EventFetcherException.cs index fe14472be6..8ef81d8ec9 100644 --- a/src/Marten/Events/Daemon/EventFetcherException.cs +++ b/src/Marten/Events/Daemon/EventFetcherException.cs @@ -1,4 +1,5 @@ using System; +using Marten.Exceptions; using Marten.Storage; namespace Marten.Events.Daemon @@ -6,7 +7,7 @@ namespace Marten.Events.Daemon /// /// Marten failed to load events for a projection shard /// - public class EventFetcherException: Exception + public class EventFetcherException: MartenException { public EventFetcherException(ShardName name, IMartenDatabase martenDatabase, Exception innerException) : base($"Failure while trying to load events for projection shard '{name}@{martenDatabase.Identifier}'", innerException) { diff --git a/src/Marten/Events/Daemon/ShardStartException.cs b/src/Marten/Events/Daemon/ShardStartException.cs index 2134cdb797..f435949e31 100644 --- a/src/Marten/Events/Daemon/ShardStartException.cs +++ b/src/Marten/Events/Daemon/ShardStartException.cs @@ -1,11 +1,12 @@ using System; +using Marten.Exceptions; namespace Marten.Events.Daemon { /// /// A projection shard failed to start /// - public class ShardStartException : Exception + public class ShardStartException : MartenException { internal ShardStartException(ShardAgent agent, Exception innerException) : base($"Failure while trying to stop '{agent.ProjectionShardIdentity}'", innerException) { diff --git a/src/Marten/Events/Daemon/ShardStopException.cs b/src/Marten/Events/Daemon/ShardStopException.cs index 4ad6d898b5..cea6a2a5e0 100644 --- a/src/Marten/Events/Daemon/ShardStopException.cs +++ b/src/Marten/Events/Daemon/ShardStopException.cs @@ -1,11 +1,12 @@ using System; +using Marten.Exceptions; namespace Marten.Events.Daemon { /// /// A projection shard failed to stop in a timely manner /// - public class ShardStopException : Exception + public class ShardStopException : MartenException { public ShardStopException(ShardName name, Exception innerException) : base($"Failure while trying to stop '{name.Identity}'", innerException) { diff --git a/src/Marten/Exceptions/AmbiguousDocumentTypeAliasesException.cs b/src/Marten/Exceptions/AmbiguousDocumentTypeAliasesException.cs index ad3a5abb14..31af64273a 100644 --- a/src/Marten/Exceptions/AmbiguousDocumentTypeAliasesException.cs +++ b/src/Marten/Exceptions/AmbiguousDocumentTypeAliasesException.cs @@ -2,7 +2,7 @@ namespace Marten.Exceptions { - public class AmbiguousDocumentTypeAliasesException: Exception + public class AmbiguousDocumentTypeAliasesException: MartenException { public AmbiguousDocumentTypeAliasesException(string message) : base(message) { diff --git a/src/Marten/Exceptions/ApplyEventException.cs b/src/Marten/Exceptions/ApplyEventException.cs index e74ccf107f..df4491b2e1 100644 --- a/src/Marten/Exceptions/ApplyEventException.cs +++ b/src/Marten/Exceptions/ApplyEventException.cs @@ -3,7 +3,7 @@ namespace Marten.Exceptions { - public class ApplyEventException : Exception + public class ApplyEventException : MartenException { public ApplyEventException(IEvent @event, Exception innerException) : base($"Failure to apply event #{@event.Sequence} ({@event.Data}.)", innerException) { diff --git a/src/Marten/Exceptions/BadLinqExpressionException.cs b/src/Marten/Exceptions/BadLinqExpressionException.cs index 769c9fcd59..a5636cd248 100644 --- a/src/Marten/Exceptions/BadLinqExpressionException.cs +++ b/src/Marten/Exceptions/BadLinqExpressionException.cs @@ -6,7 +6,7 @@ namespace Marten.Exceptions [Serializable] #endif - public class BadLinqExpressionException: Exception + public class BadLinqExpressionException: MartenException { public BadLinqExpressionException(string message, Exception innerException) : base(message, innerException) { diff --git a/src/Marten/Exceptions/ConcurrencyException.cs b/src/Marten/Exceptions/ConcurrencyException.cs index 85a3fe721b..d4abdfb61c 100644 --- a/src/Marten/Exceptions/ConcurrencyException.cs +++ b/src/Marten/Exceptions/ConcurrencyException.cs @@ -3,7 +3,7 @@ namespace Marten.Exceptions { - public class ConcurrencyException: Exception + public class ConcurrencyException: MartenException { public string DocType { get; set; } public object Id { get; set; } diff --git a/src/Marten/Exceptions/ConcurrentUpdateException.cs b/src/Marten/Exceptions/ConcurrentUpdateException.cs index 50062f2d0b..2f1a724b3e 100644 --- a/src/Marten/Exceptions/ConcurrentUpdateException.cs +++ b/src/Marten/Exceptions/ConcurrentUpdateException.cs @@ -3,7 +3,7 @@ namespace Marten.Exceptions { - public class ConcurrentUpdateException: Exception + public class ConcurrentUpdateException: MartenException { public ConcurrentUpdateException(Exception innerException) : base("Write collision detected while commiting the transaction.", innerException) { diff --git a/src/Marten/Exceptions/DefaultTenantUsageDisabledException.cs b/src/Marten/Exceptions/DefaultTenantUsageDisabledException.cs index 9f21765696..e2313cf83c 100644 --- a/src/Marten/Exceptions/DefaultTenantUsageDisabledException.cs +++ b/src/Marten/Exceptions/DefaultTenantUsageDisabledException.cs @@ -4,7 +4,7 @@ namespace Marten.Exceptions { - public class DefaultTenantUsageDisabledException : Exception + public class DefaultTenantUsageDisabledException : MartenException { public DefaultTenantUsageDisabledException() : base($"Default tenant {Tenancy.DefaultTenantId} usage is disabled. Ensure to create a session by explicitly passing a non-default tenant in the method arg or SessionOptions.") diff --git a/src/Marten/Exceptions/DocumentAlreadyExistsException.cs b/src/Marten/Exceptions/DocumentAlreadyExistsException.cs index 718e8b52ac..c1646b988d 100644 --- a/src/Marten/Exceptions/DocumentAlreadyExistsException.cs +++ b/src/Marten/Exceptions/DocumentAlreadyExistsException.cs @@ -3,7 +3,7 @@ namespace Marten.Exceptions { - public sealed class DocumentAlreadyExistsException: Exception + public sealed class DocumentAlreadyExistsException: MartenException { public Type DocType { get; } public object Id { get; } diff --git a/src/Marten/Exceptions/DocumentIdTypeMismatchException.cs b/src/Marten/Exceptions/DocumentIdTypeMismatchException.cs index ce131b1d1a..42a2f5bfba 100644 --- a/src/Marten/Exceptions/DocumentIdTypeMismatchException.cs +++ b/src/Marten/Exceptions/DocumentIdTypeMismatchException.cs @@ -5,7 +5,7 @@ namespace Marten.Exceptions { - public class DocumentIdTypeMismatchException : Exception + public class DocumentIdTypeMismatchException : MartenException { public DocumentIdTypeMismatchException(IDocumentStorage storage, Type actualIdType) : base($"Id/Document type mismatch. The id type for the included document type {storage.SourceType.FullNameInCode()} is {storage.IdType.FullNameInCode()}, but {actualIdType.NameInCode()} was used.") { diff --git a/src/Marten/Exceptions/EmptyEventStreamException.cs b/src/Marten/Exceptions/EmptyEventStreamException.cs index 70b781c1d7..8cf15b6016 100644 --- a/src/Marten/Exceptions/EmptyEventStreamException.cs +++ b/src/Marten/Exceptions/EmptyEventStreamException.cs @@ -3,7 +3,7 @@ namespace Marten.Exceptions { - public class EmptyEventStreamException : Exception + public class EmptyEventStreamException : MartenException { public static readonly string MessageTemplate = "A new event stream ('{0}') cannot be started without any events"; diff --git a/src/Marten/Exceptions/ExistingStreamIdCollisionException.cs b/src/Marten/Exceptions/ExistingStreamIdCollisionException.cs index c44f9f52c8..6c9f21d604 100644 --- a/src/Marten/Exceptions/ExistingStreamIdCollisionException.cs +++ b/src/Marten/Exceptions/ExistingStreamIdCollisionException.cs @@ -3,7 +3,7 @@ namespace Marten.Exceptions { - public class ExistingStreamIdCollisionException: Exception + public class ExistingStreamIdCollisionException: MartenException { public object Id { get; } diff --git a/src/Marten/Exceptions/HiloSequenceAdvanceToNextHiAttemptsExceededException.cs b/src/Marten/Exceptions/HiloSequenceAdvanceToNextHiAttemptsExceededException.cs index 5e11acb1c1..c99ded41ce 100644 --- a/src/Marten/Exceptions/HiloSequenceAdvanceToNextHiAttemptsExceededException.cs +++ b/src/Marten/Exceptions/HiloSequenceAdvanceToNextHiAttemptsExceededException.cs @@ -3,7 +3,7 @@ namespace Marten.Exceptions { - public class HiloSequenceAdvanceToNextHiAttemptsExceededException : Exception + public class HiloSequenceAdvanceToNextHiAttemptsExceededException : MartenException { private const string message = "Advance to next hilo sequence retry limit exceeded. Unable to secure next hi sequence"; public HiloSequenceAdvanceToNextHiAttemptsExceededException() : base(message) diff --git a/src/Marten/Exceptions/InvalidCompiledQueryException.cs b/src/Marten/Exceptions/InvalidCompiledQueryException.cs index d3f8a44cdb..1d203612b1 100644 --- a/src/Marten/Exceptions/InvalidCompiledQueryException.cs +++ b/src/Marten/Exceptions/InvalidCompiledQueryException.cs @@ -5,7 +5,7 @@ namespace Marten.Exceptions { - public class InvalidCompiledQueryException: Exception + public class InvalidCompiledQueryException: MartenException { public static readonly string CompiledQueryTypeCannotBeAsyncMessage = "Invalid compiled query type `{0}`. Compiled queries cannot use asynchronous query selectors like 'CountAsync()'. Please use the synchronous equivalent like 'Count()' instead. You will still be able to query asynchronously through IQuerySession.QueryAsync()."; diff --git a/src/Marten/Exceptions/InvalidDocumentException.cs b/src/Marten/Exceptions/InvalidDocumentException.cs index b6623920af..80020575c5 100644 --- a/src/Marten/Exceptions/InvalidDocumentException.cs +++ b/src/Marten/Exceptions/InvalidDocumentException.cs @@ -6,7 +6,7 @@ namespace Marten.Exceptions [Serializable] #endif - public class InvalidDocumentException: Exception + public class InvalidDocumentException: MartenException { public InvalidDocumentException(string message) : base(message) { diff --git a/src/Marten/Exceptions/InvalidProjectionException.cs b/src/Marten/Exceptions/InvalidProjectionException.cs index 7f547464bb..8b6a712122 100644 --- a/src/Marten/Exceptions/InvalidProjectionException.cs +++ b/src/Marten/Exceptions/InvalidProjectionException.cs @@ -12,7 +12,7 @@ namespace Marten.Exceptions /// /// Thrown when any configuration rules for an active projection are violated and the projection is invalid /// - public class InvalidProjectionException : Exception + public class InvalidProjectionException : MartenException { public InvalidProjectionException(string message) : base(message) { diff --git a/src/Marten/Exceptions/InvalidStreamOperationException.cs b/src/Marten/Exceptions/InvalidStreamOperationException.cs index 219c4870d5..b0733d2d27 100644 --- a/src/Marten/Exceptions/InvalidStreamOperationException.cs +++ b/src/Marten/Exceptions/InvalidStreamOperationException.cs @@ -2,7 +2,7 @@ namespace Marten.Exceptions { - public class InvalidStreamOperationException: Exception + public class InvalidStreamOperationException: MartenException { public InvalidStreamOperationException(string message): base(message) diff --git a/src/Marten/Exceptions/InvalidUtcDateTimeUsageException.cs b/src/Marten/Exceptions/InvalidUtcDateTimeUsageException.cs index d788a1a048..6deca1b85d 100644 --- a/src/Marten/Exceptions/InvalidUtcDateTimeUsageException.cs +++ b/src/Marten/Exceptions/InvalidUtcDateTimeUsageException.cs @@ -3,7 +3,7 @@ #nullable enable namespace Marten.Exceptions { - public class InvalidUtcDateTimeUsageException : Exception + public class InvalidUtcDateTimeUsageException : MartenException { public InvalidUtcDateTimeUsageException(Exception inner) : base("DateTime with Kind=UTC is no longer supported by Npgsql. Consider switching to DateTimeOffset or NodaTime wherever possible, or see https://www.npgsql.org/efcore/release-notes/6.0.html.", inner) { diff --git a/src/Marten/Exceptions/MartenCommandException.cs b/src/Marten/Exceptions/MartenCommandException.cs index 6261c0abeb..ff6b61558e 100644 --- a/src/Marten/Exceptions/MartenCommandException.cs +++ b/src/Marten/Exceptions/MartenCommandException.cs @@ -6,7 +6,7 @@ namespace Marten.Exceptions /// /// Wraps the Postgres command exceptions. Unifies exception handling and brings additonal information. /// - public class MartenCommandException: Exception + public class MartenCommandException: MartenException { public const string MaybeLockedRowsMessage = "Postgresql timed out while trying to read data. This may be caused by trying to read locked rows"; diff --git a/src/Marten/Exceptions/MartenException.cs b/src/Marten/Exceptions/MartenException.cs new file mode 100644 index 0000000000..af9af4fd67 --- /dev/null +++ b/src/Marten/Exceptions/MartenException.cs @@ -0,0 +1,27 @@ +using System; +using System.Runtime.Serialization; + +namespace Marten.Exceptions +{ + /// + /// Base class for all Marten related exceptions + /// + public class MartenException : Exception + { + public MartenException() + { + } + + protected MartenException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + + public MartenException(string message) : base(message) + { + } + + public MartenException(string message, Exception innerException) : base(message, innerException) + { + } + } +} diff --git a/src/Marten/Exceptions/MartenSchemaException.cs b/src/Marten/Exceptions/MartenSchemaException.cs index 4c7c9dedbb..22af80ad8e 100644 --- a/src/Marten/Exceptions/MartenSchemaException.cs +++ b/src/Marten/Exceptions/MartenSchemaException.cs @@ -6,7 +6,7 @@ namespace Marten.Exceptions [Serializable] #endif - public class MartenSchemaException: Exception + public class MartenSchemaException: MartenException { public MartenSchemaException(object subject, string ddl, Exception inner) : base($"DDL Execution for '{subject}' Failed!\n\n{ddl}", inner) { diff --git a/src/Marten/Exceptions/NonExistentDocumentException.cs b/src/Marten/Exceptions/NonExistentDocumentException.cs index f9e6e94b67..fe732416e2 100644 --- a/src/Marten/Exceptions/NonExistentDocumentException.cs +++ b/src/Marten/Exceptions/NonExistentDocumentException.cs @@ -3,7 +3,7 @@ namespace Marten.Exceptions { - public class NonExistentDocumentException: Exception + public class NonExistentDocumentException: MartenException { public Type DocType { get; } public object Id { get; } diff --git a/src/Marten/Exceptions/NonExistentStreamException.cs b/src/Marten/Exceptions/NonExistentStreamException.cs index 55e0ad2039..f66018fde5 100644 --- a/src/Marten/Exceptions/NonExistentStreamException.cs +++ b/src/Marten/Exceptions/NonExistentStreamException.cs @@ -2,7 +2,7 @@ namespace Marten.Exceptions { - public class NonExistentStreamException: Exception + public class NonExistentStreamException: MartenException { public object Id { get; } diff --git a/src/Marten/Exceptions/ProgressionProgressOutOfOrderException.cs b/src/Marten/Exceptions/ProgressionProgressOutOfOrderException.cs index a803f2d86e..f6b0a386a9 100644 --- a/src/Marten/Exceptions/ProgressionProgressOutOfOrderException.cs +++ b/src/Marten/Exceptions/ProgressionProgressOutOfOrderException.cs @@ -3,7 +3,7 @@ namespace Marten.Exceptions { - public class ProgressionProgressOutOfOrderException : Exception + public class ProgressionProgressOutOfOrderException : MartenException { public ProgressionProgressOutOfOrderException(ShardName progressionOrShardName) : base($"Progression '{progressionOrShardName}' is out of order. This may happen when multiple processes try to process the projection") { diff --git a/src/Marten/Exceptions/RollbackException.cs b/src/Marten/Exceptions/RollbackException.cs index c670f6a548..46abd06b9e 100644 --- a/src/Marten/Exceptions/RollbackException.cs +++ b/src/Marten/Exceptions/RollbackException.cs @@ -3,7 +3,7 @@ namespace Marten.Exceptions { - public class RollbackException: Exception + public class RollbackException: MartenException { public RollbackException(Exception innerException) : base("Failed while trying to rollback an exception", innerException) { diff --git a/src/Marten/Exceptions/StreamLockedException.cs b/src/Marten/Exceptions/StreamLockedException.cs index 65e6dfa181..2ab6daee44 100644 --- a/src/Marten/Exceptions/StreamLockedException.cs +++ b/src/Marten/Exceptions/StreamLockedException.cs @@ -2,7 +2,7 @@ namespace Marten.Exceptions { - public class StreamLockedException : Exception + public class StreamLockedException : MartenException { public StreamLockedException(object streamId, Exception innerException) : base($"Stream '{streamId}' may be locked for updates") { diff --git a/src/Marten/Exceptions/UnknownEventTypeException.cs b/src/Marten/Exceptions/UnknownEventTypeException.cs index dfd1fe8df4..7129b61bac 100644 --- a/src/Marten/Exceptions/UnknownEventTypeException.cs +++ b/src/Marten/Exceptions/UnknownEventTypeException.cs @@ -3,7 +3,7 @@ namespace Marten.Exceptions { - public class UnknownEventTypeException: Exception + public class UnknownEventTypeException: MartenException { public UnknownEventTypeException(string eventTypeName) : base((string)$"Unknown event type name alias '{eventTypeName}.' You may need to register this event type through StoreOptions.Events.AddEventType(type)") { diff --git a/src/Marten/Storage/ITenancy.cs b/src/Marten/Storage/ITenancy.cs index 9ffaaa8dcf..4d198f6e62 100644 --- a/src/Marten/Storage/ITenancy.cs +++ b/src/Marten/Storage/ITenancy.cs @@ -1,5 +1,6 @@ using System; using System.Threading.Tasks; +using Marten.Exceptions; using Marten.Schema; using Weasel.Core.Migrations; @@ -49,7 +50,7 @@ public interface ITenancy : IDatabaseSource #endregion - public class UnknownTenantIdException: Exception + public class UnknownTenantIdException: MartenException { public UnknownTenantIdException(string tenantId) : base($"Unknown tenant id '{tenantId}'") {