From eba7bf50d4766ca7160edad6af18bdaf4970fbc7 Mon Sep 17 00:00:00 2001 From: Gregorius Soedharmo Date: Wed, 12 Oct 2022 15:43:49 +0700 Subject: [PATCH] [PORT #6167] Improve error/exception message for misconfigured cluster provider (#6169) * Improve error/exception message for misconfigured cluster provider (#6167) * Improve error/exception message for misconfigured cluster provider * Remove pattern matching * Improve validation to also catch other invalid configuration scenario * Simplify code * Update API Verify list (cherry picked from commit 5f8710d9ce016227b1e73e9c2dc1957f74508b19) * Update API Verify list --- .../InvalidSettingsSpec.cs | 26 ++++++++++++++++ .../CoreAPISpec.ApproveCore.Core.verified.txt | 2 +- ...oreAPISpec.ApproveCore.DotNet.verified.txt | 2 +- .../CoreAPISpec.ApproveCore.Net.verified.txt | 2 +- .../CoreAPISpec.ApproveCore.verified.txt | 2 +- .../InvalidClusterSettingsSpec.cs | 31 +++++++++++++++++++ src/core/Akka.Cluster/ClusterSettings.cs | 4 +-- .../Configuration/ConfigurationException.cs | 6 ++-- 8 files changed, 66 insertions(+), 9 deletions(-) create mode 100644 src/contrib/cluster/Akka.Cluster.Sharding.Tests/InvalidSettingsSpec.cs create mode 100644 src/core/Akka.Cluster.Tests/InvalidClusterSettingsSpec.cs diff --git a/src/contrib/cluster/Akka.Cluster.Sharding.Tests/InvalidSettingsSpec.cs b/src/contrib/cluster/Akka.Cluster.Sharding.Tests/InvalidSettingsSpec.cs new file mode 100644 index 00000000000..d962cf1f5c5 --- /dev/null +++ b/src/contrib/cluster/Akka.Cluster.Sharding.Tests/InvalidSettingsSpec.cs @@ -0,0 +1,26 @@ +// ----------------------------------------------------------------------- +// +// Copyright (C) 2009-2022 Lightbend Inc. +// Copyright (C) 2013-2022 .NET Foundation +// +// ----------------------------------------------------------------------- + +using Akka.Configuration; +using Akka.TestKit; +using FluentAssertions; +using Xunit; +using static FluentAssertions.FluentActions; + +namespace Akka.Cluster.Sharding.Tests +{ + public class InvalidSettingsSpec: AkkaSpec + { + [Fact(DisplayName = "ClusterSharding started with invalid actor provider should raise a user friendly exception")] + public void InvalidActorProviderTest() + { + Invoking(() => ClusterSharding.Get(Sys)) // throws here + .Should().ThrowExactly() + .WithMessage("*Did you forgot*"); + } + } +} \ No newline at end of file diff --git a/src/core/Akka.API.Tests/verify/CoreAPISpec.ApproveCore.Core.verified.txt b/src/core/Akka.API.Tests/verify/CoreAPISpec.ApproveCore.Core.verified.txt index bf8e5ced88a..d0d14a120a7 100644 --- a/src/core/Akka.API.Tests/verify/CoreAPISpec.ApproveCore.Core.verified.txt +++ b/src/core/Akka.API.Tests/verify/CoreAPISpec.ApproveCore.Core.verified.txt @@ -2206,7 +2206,7 @@ namespace Akka.Configuration public ConfigurationException(string message) { } public ConfigurationException(string message, System.Exception exception) { } protected ConfigurationException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } - public static Akka.Configuration.ConfigurationException NullOrEmptyConfig(string path = null) { } + public static Akka.Configuration.ConfigurationException NullOrEmptyConfig(string path = null, string reason = null) { } } public class ConfigurationFactory { diff --git a/src/core/Akka.API.Tests/verify/CoreAPISpec.ApproveCore.DotNet.verified.txt b/src/core/Akka.API.Tests/verify/CoreAPISpec.ApproveCore.DotNet.verified.txt index fe3e5ec9e1e..a54bf23c3ae 100644 --- a/src/core/Akka.API.Tests/verify/CoreAPISpec.ApproveCore.DotNet.verified.txt +++ b/src/core/Akka.API.Tests/verify/CoreAPISpec.ApproveCore.DotNet.verified.txt @@ -2208,7 +2208,7 @@ namespace Akka.Configuration public ConfigurationException(string message) { } public ConfigurationException(string message, System.Exception exception) { } protected ConfigurationException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } - public static Akka.Configuration.ConfigurationException NullOrEmptyConfig(string path = null) { } + public static Akka.Configuration.ConfigurationException NullOrEmptyConfig(string path = null, string reason = null) { } } public class ConfigurationFactory { diff --git a/src/core/Akka.API.Tests/verify/CoreAPISpec.ApproveCore.Net.verified.txt b/src/core/Akka.API.Tests/verify/CoreAPISpec.ApproveCore.Net.verified.txt index bf8e5ced88a..d0d14a120a7 100644 --- a/src/core/Akka.API.Tests/verify/CoreAPISpec.ApproveCore.Net.verified.txt +++ b/src/core/Akka.API.Tests/verify/CoreAPISpec.ApproveCore.Net.verified.txt @@ -2206,7 +2206,7 @@ namespace Akka.Configuration public ConfigurationException(string message) { } public ConfigurationException(string message, System.Exception exception) { } protected ConfigurationException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } - public static Akka.Configuration.ConfigurationException NullOrEmptyConfig(string path = null) { } + public static Akka.Configuration.ConfigurationException NullOrEmptyConfig(string path = null, string reason = null) { } } public class ConfigurationFactory { diff --git a/src/core/Akka.API.Tests/verify/CoreAPISpec.ApproveCore.verified.txt b/src/core/Akka.API.Tests/verify/CoreAPISpec.ApproveCore.verified.txt index c04f2b3a683..4fe26df91c6 100644 --- a/src/core/Akka.API.Tests/verify/CoreAPISpec.ApproveCore.verified.txt +++ b/src/core/Akka.API.Tests/verify/CoreAPISpec.ApproveCore.verified.txt @@ -2239,7 +2239,7 @@ namespace Akka.Configuration public ConfigurationException(string message) { } public ConfigurationException(string message, System.Exception exception) { } protected ConfigurationException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } - public static Akka.Configuration.ConfigurationException NullOrEmptyConfig(string path = null) { } + public static Akka.Configuration.ConfigurationException NullOrEmptyConfig(string path = null, string reason = null) { } } public class ConfigurationFactory { diff --git a/src/core/Akka.Cluster.Tests/InvalidClusterSettingsSpec.cs b/src/core/Akka.Cluster.Tests/InvalidClusterSettingsSpec.cs new file mode 100644 index 00000000000..a1736ee756e --- /dev/null +++ b/src/core/Akka.Cluster.Tests/InvalidClusterSettingsSpec.cs @@ -0,0 +1,31 @@ +// ----------------------------------------------------------------------- +// +// Copyright (C) 2009-2022 Lightbend Inc. +// Copyright (C) 2013-2022 .NET Foundation +// +// ----------------------------------------------------------------------- + +using Akka.Configuration; +using Akka.TestKit; +using FluentAssertions; +using Xunit; +using Xunit.Abstractions; +using static FluentAssertions.FluentActions; + +namespace Akka.Cluster.Tests +{ + public class InvalidClusterSettingsSpec : AkkaSpec + { + public InvalidClusterSettingsSpec(ITestOutputHelper output) : base(output) + { + } + + [Fact(DisplayName = "Cluster started with invalid actor provider should raise a user friendly exception")] + public void InvalidActorProviderTest() + { + Invoking(() => Cluster.Get(Sys)) // throws here + .Should().ThrowExactly() + .WithMessage("*Did you forgot*"); + } + } +} \ No newline at end of file diff --git a/src/core/Akka.Cluster/ClusterSettings.cs b/src/core/Akka.Cluster/ClusterSettings.cs index 53cddd04a2f..5c0db957add 100644 --- a/src/core/Akka.Cluster/ClusterSettings.cs +++ b/src/core/Akka.Cluster/ClusterSettings.cs @@ -34,8 +34,8 @@ public ClusterSettings(Config config, string systemName) { //TODO: Requiring! var clusterConfig = config.GetConfig("akka.cluster"); - if (clusterConfig.IsNullOrEmpty()) - throw ConfigurationException.NullOrEmptyConfig("akka.cluster"); + if (clusterConfig?.GetConfig("failure-detector") == null) + throw ConfigurationException.NullOrEmptyConfig("akka.cluster", "Did you forgot to set the 'akka.cluster.provider' HOCON property to 'cluster'?"); LogInfoVerbose = clusterConfig.GetBoolean("log-info-verbose", false); LogInfo = LogInfoVerbose || clusterConfig.GetBoolean("log-info", false); diff --git a/src/core/Akka/Configuration/ConfigurationException.cs b/src/core/Akka/Configuration/ConfigurationException.cs index dba5d7b2ea0..c66f7ce884c 100644 --- a/src/core/Akka/Configuration/ConfigurationException.cs +++ b/src/core/Akka/Configuration/ConfigurationException.cs @@ -16,11 +16,11 @@ namespace Akka.Configuration /// public class ConfigurationException : AkkaException { - public static ConfigurationException NullOrEmptyConfig(string path = null) + public static ConfigurationException NullOrEmptyConfig(string path = null, string reason = null) { if (!string.IsNullOrWhiteSpace(path)) - return new ConfigurationException($"Failed to instantiate {typeof(T).Name}: Configuration does not contain `{path}` node"); - return new ConfigurationException($"Failed to instantiate {typeof(T).Name}: Configuration is null or empty."); + return new ConfigurationException($"Failed to instantiate {typeof(T).Name}: Configuration does not contain `{path}` node{(reason != null ? $". {reason}" : "")}"); + return new ConfigurationException($"Failed to instantiate {typeof(T).Name}: Configuration is null or empty{(reason != null ? $". {reason}" : "")}"); } ///