Skip to content

Commit

Permalink
Add OnFailureCreated callback
Browse files Browse the repository at this point in the history
  • Loading branch information
JeremySkinner committed Jul 4, 2023
1 parent aa61b35 commit 0eaf52c
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 0 deletions.
43 changes: 43 additions & 0 deletions src/FluentValidation.Tests/OnFailureHookTester.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#region License
// Copyright (c) .NET Foundation and contributors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// The latest version of this file can be found at https://github.com/FluentValidation/FluentValidation
#endregion

namespace FluentValidation.Tests;

using Xunit;

public class OnFailureHookTester {

[Fact]
public void Runs_hook_when_failure_created() {
try {
ValidatorOptions.Global.OnFailureCreated = (failure, context, propertyValue, rule, component) => {
failure.PropertyName = "Foo";
return failure;
};

var validator = new InlineValidator<Person>();
validator.RuleFor(x => x.Surname).NotNull();
var result = validator.Validate(new Person());
result.Errors[0].PropertyName.ShouldEqual("Foo");
}
finally {
ValidatorOptions.Global.OnFailureCreated = null;
}

}
}
4 changes: 4 additions & 0 deletions src/FluentValidation/Internal/RuleBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,10 @@ public string GetDisplayName(ValidationContext<T> context)
failure.CustomState = component.CustomStateProvider(context, value);
}

if (ValidatorOptions.Global.OnFailureCreated != null) {
failure = ValidatorOptions.Global.OnFailureCreated(failure, context, value, this, component);
}

return failure;
}
}
7 changes: 7 additions & 0 deletions src/FluentValidation/ValidatorOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@ namespace FluentValidation;

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq.Expressions;
using System.Reflection;
using Internal;
using Resources;
using Results;
using Validators;

/// <summary>
Expand Down Expand Up @@ -198,6 +200,11 @@ public class ValidatorConfiguration {
set => _errorCodeResolver = value ?? DefaultErrorCodeResolver;
}

/// <summary>
/// Defines a hook that runs when a <see cref="ValidationFailure"/> is created.
/// </summary>
public Func<ValidationFailure, IValidationContext, object, IValidationRule, IRuleComponent, ValidationFailure> OnFailureCreated { get; set; }

static string DefaultPropertyNameResolver(Type type, MemberInfo memberInfo, LambdaExpression expression) {
if (expression != null) {
var chain = PropertyChain.FromExpression(expression);
Expand Down

0 comments on commit 0eaf52c

Please sign in to comment.