Skip to content

Commit

Permalink
better exception message for numeric revision fails when using Store(…
Browse files Browse the repository at this point in the history
…IRevisioned)
  • Loading branch information
jeremydmiller committed May 14, 2024
1 parent 2d55a23 commit f043c31
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 11 deletions.
17 changes: 9 additions & 8 deletions src/DocumentDbTests/Concurrency/numeric_revisioning.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System;
using System.Threading.Tasks;
using Castle.Components.DictionaryAdapter;
using JasperFx.CodeGeneration;
using JasperFx.Core;
using Marten.Exceptions;
using Marten.Metadata;
using Marten.Schema;
Expand Down Expand Up @@ -133,23 +135,22 @@ public async Task each_store_should_increase_the_version()
{
var doc1 = new RevisionedDoc { Name = "Tim" };
theSession.Store(doc1);
theSession.SaveChanges();
await theSession.SaveChangesAsync();
doc1.Version.ShouldBe(1);

doc1.Name = "Brad";
theSession.Store(doc1);
theSession.SaveChanges();
await theSession.SaveChangesAsync();
doc1.Version.ShouldBe(2);

doc1.Name = "Janet";
theSession.Store(doc1);
theSession.SaveChanges();
doc1.Version.ShouldBe(3);

doc1.Name = "Arthur";
theSession.Store(doc1);
theSession.SaveChanges();
doc1.Version.ShouldBe(4);
// It's going to warn you to use UpdateRevision here.
var ex = await Should.ThrowAsync<ConcurrencyException>(async () =>
{
await theSession.SaveChangesAsync();
});
}

[Fact]
Expand Down
17 changes: 15 additions & 2 deletions src/Marten/Exceptions/ConcurrencyException.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,25 @@
using System;
using System.Runtime.Serialization;
using JasperFx.Core.Reflection;
using Marten.Metadata;

namespace Marten.Exceptions;

public class ConcurrencyException: MartenException
{
public ConcurrencyException(Type docType, object id): base(
$"Optimistic concurrency check failed for {docType.FullName} #{id}")
public static string ToMessage(Type docType, object id)
{
var message = $"Optimistic concurrency check failed for {docType.FullName} #{id}";
if (docType.CanBeCastTo<IRevisioned>())
{
message +=
$". For documents of type {typeof(IRevisioned).FullNameInCode()}, Marten uses the current value of {nameof(IRevisioned)}.{nameof(IRevisioned.Version)} as the revision when IDocumentSession.Store() is called. You may need to explicitly call IDocumentSession.UpdateRevision() instead, or set the expected version correctly on the document itself";
}

return message;
}

public ConcurrencyException(Type docType, object id): base(ToMessage(docType, id))
{
DocType = docType.FullName;
Id = id;
Expand Down
2 changes: 1 addition & 1 deletion src/Marten/Internal/Operations/StorageOperation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ protected async Task<bool> postprocessRevisionAsync(DbDataReader reader, IList<E
var revision = await reader.GetFieldValueAsync<int>(0, token).ConfigureAwait(false);
if (Revision > 1) // don't care about zero or 1
{
if (revision > Revision)
if (revision >= Revision)
{
exceptions.Add(new ConcurrencyException(typeof(T), _id));
success = false;
Expand Down
1 change: 1 addition & 0 deletions src/Marten/Storage/Metadata/RevisionColumn.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public RevisionColumn(): base(SchemaConstants.VersionColumn, x => x.CurrentRevis
AllowNulls = false;
DefaultExpression = "0";
Enabled = false;
ShouldUpdatePartials = true;
}

internal override UpsertArgument ToArgument()
Expand Down

0 comments on commit f043c31

Please sign in to comment.