U4-10003 - Health Check Throws Exception When Messages Aren't Overridden

Created by Nicholas Westby 09 Jun 2017, 21:18:38 Updated by Nicholas Westby 09 Jun 2017, 21:18:38

If you create a health check that derives from AbstractConfigCheck and you use the built-in versions of the CheckSuccessMessage and CheckErrorMessage, you'll get an error unless one of your values has the IsRecommended property set to true. The reason seems to be these lines:

This will throw an operation invalid exception:

Values.First(v => v.IsRecommended).Value

If none of the values are recommended, the First will fail. Here's the stack trace:

2017-06-09 14:08:14,255 [P7868/D2/T14] ERROR Umbraco.Web.HealthCheck.HealthCheckController - Exception in health check: Check Robotnik System.InvalidOperationException: Sequence contains no matching element at System.Linq.Enumerable.First[TSource](IEnumerable1 source, Func2 predicate) at Umbraco.Web.HealthCheck.Checks.Config.AbstractConfigCheck.get_CheckErrorMessage() at Umbraco.Web.HealthCheck.Checks.Config.AbstractConfigCheck.GetStatus() at Umbraco.Web.HealthCheck.HealthCheckController.GetStatus(Guid id)

Here's a health check that demonstrates this:

// Namespaces. using System.Collections.Generic; using Umbraco.Web.HealthCheck; using Umbraco.Web.HealthCheck.Checks.Config;

/// <summary>
/// A health check that ensures the sample Robotnik domain is not being used.
/// </summary>
[HealthCheck("B878A830-6DE4-4352-9283-4B867DCF7C75",
    "Check Robotnik", Description = CheckDescription, Group = "Live Environment")]
public class RobotnikCheck : AbstractConfigCheck
{

    #region Constants

    private const string CheckDescription = "Checks the Robotnik configuration in the web.config to ensure you aren't still using the default sample domain.";

    #endregion

    #region Constructors

    /// <summary>
    /// Primary constructor (required by base class).
    /// </summary>
    /// <param name="healthCheckContext">
    /// The health check context.
    /// </param>
    public RobotnikCheck(HealthCheckContext healthCheckContext) : base(healthCheckContext)
    {
    }

    #endregion

    #region Properties

    /// <summary>
    /// The path to the config file.
    /// </summary>
    public override string FilePath => "~/Web.config";

    /// <summary>
    /// The type of comparison to perform against the values.
    /// </summary>
    public override ValueComparisonType ValueComparisonType => ValueComparisonType.ShouldNotEqual;

    /// <summary>
    /// The values to compare against the value in the configuration file.
    /// </summary>
    public override IEnumerable<AcceptableConfiguration> Values => new[]
    {
        new AcceptableConfiguration()
        {
            IsRecommended = false,
            Value = "robotnik-www.some-site.com"
        }
    };

    /// <summary>
    /// The XPath expression to use to locate the attribute with the value to check.
    /// </summary>
    public override string XPath => @"/configuration/appSettings/add[@value=""~/robots-primary.txt""][@key!=""robotnik-localhost""][1]/@key";

    // Commenting these out to demonstrate the error.
    /*
    /// <summary>
    /// The success message to show when the health check has passed.
    /// </summary>
    public override string CheckSuccessMessage => "The sample Robotnik domain is no longer being used. That probably means you've replaced it with the correct domain.";

    /// <summary>
    /// The error message to show when the health check has failed to pass.
    /// </summary>
    public override string CheckErrorMessage => @"The sample Robotnik domain is still being used. You should change it to the correct domain. For example, if you are working with www.microsoft.com, the value would be ""robotnik-www.microsoft.com"".";

    /// <summary>
    /// The message to show when a failed health check has been successfully rectified.
    /// </summary>
    public override string RectifySuccessMessage => "The Robotnik domain has been updated to the one you specified. Edit the web.config if you have more domains to add.";
    */

    #endregion

}{code}

And here are the app settings in my web.config:

Umbraco 7.5.13.

Comments

Priority: Normal

Type: Bug

State: Submitted

Assignee:

Difficulty: Normal

Category:

Backwards Compatible: True

Fix Submitted:

Affected versions: 7.5.13

Due in version:

Sprint:

Story Points:

Cycle: