IGNITE-5441 .NET: Propagate CacheStore exception stack traces to the caller node
This closes #2247 Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/c396b0bc Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/c396b0bc Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/c396b0bc Branch: refs/heads/ignite-2.1 Commit: c396b0bcfa5f959013c94ece47dc1111fa650d97 Parents: 333e32b Author: Pavel Tupitsyn <[email protected]> Authored: Thu Jul 6 13:03:50 2017 +0300 Committer: Pavel Tupitsyn <[email protected]> Committed: Thu Jul 6 13:03:50 2017 +0300 ---------------------------------------------------------------------- .../Cache/CacheAbstractTest.cs | 26 +++++++++----------- .../Cache/PersistentStoreTest.cs | 1 - .../Cache/Store/CacheStoreTest.cs | 21 +++++++++++++--- .../Apache.Ignite.Core/Common/JavaException.cs | 15 ++++++++++- .../Apache.Ignite.Core/Impl/ExceptionUtils.cs | 5 ++-- 5 files changed, 44 insertions(+), 24 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/c396b0bc/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAbstractTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAbstractTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAbstractTest.cs index 351c25c..9e44720 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAbstractTest.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAbstractTest.cs @@ -2091,26 +2091,22 @@ namespace Apache.Ignite.Core.Tests.Cache () => cache.Invoke(key, new T { ThrowErrNonSerializable = true }, arg), "ExpectedException"); } + /// <summary> + /// Asserts that specified action throws a CacheEntryProcessorException. + /// </summary> private static void AssertThrowsCacheEntryProcessorException(Action action, string containsText = null) { - try - { - action(); + var ex = Assert.Throws<CacheEntryProcessorException>(() => action()); - Assert.Fail(); + Assert.IsInstanceOf<JavaException>(ex.InnerException); + + if (string.IsNullOrEmpty(containsText)) + { + Assert.AreEqual(AddArgCacheEntryProcessor.ExceptionText, ex.GetBaseException().Message); } - catch (Exception ex) + else { - Assert.IsInstanceOf<CacheEntryProcessorException>(ex); - - if (string.IsNullOrEmpty(containsText)) - { - Assert.IsNotNull(ex.InnerException); - Assert.AreEqual(AddArgCacheEntryProcessor.ExceptionText, ex.InnerException.Message); - } - else - Assert.IsTrue(ex.ToString().Contains(containsText), - "Expected: " + containsText + ", actual: " + ex); + Assert.IsTrue(ex.ToString().Contains(containsText), "Expected: " + containsText + ", actual: " + ex); } } http://git-wip-us.apache.org/repos/asf/ignite/blob/c396b0bc/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/PersistentStoreTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/PersistentStoreTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/PersistentStoreTest.cs index cc72147..adb91ef 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/PersistentStoreTest.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/PersistentStoreTest.cs @@ -18,7 +18,6 @@ namespace Apache.Ignite.Core.Tests.Cache { using Apache.Ignite.Core.Common; - using Apache.Ignite.Core.Configuration; using Apache.Ignite.Core.PersistentStore; using NUnit.Framework; http://git-wip-us.apache.org/repos/asf/ignite/blob/c396b0bc/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Store/CacheStoreTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Store/CacheStoreTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Store/CacheStoreTest.cs index 12c442d..e05f4bd 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Store/CacheStoreTest.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Store/CacheStoreTest.cs @@ -24,6 +24,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Store using Apache.Ignite.Core.Binary; using Apache.Ignite.Core.Cache; using Apache.Ignite.Core.Cache.Store; + using Apache.Ignite.Core.Common; using Apache.Ignite.Core.Impl; using NUnit.Framework; @@ -203,6 +204,9 @@ namespace Apache.Ignite.Core.Tests.Cache.Store Assert.AreEqual(1, cache.GetSize()); } + /// <summary> + /// Tests that exceptions from user code are propagated properly. + /// </summary> [Test] public void TestExceptions() { @@ -211,7 +215,18 @@ namespace Apache.Ignite.Core.Tests.Cache.Store cache.Put(1, "val"); CacheTestStore.ThrowError = true; - CheckCustomStoreError(Assert.Throws<CacheStoreException>(() => cache.Put(-2, "fail")).InnerException); + + var ex = Assert.Throws<CacheStoreException>(() => cache.Put(-2, "fail")); + + Assert.IsTrue(ex.ToString().Contains( + "at Apache.Ignite.Core.Tests.Cache.Store.CacheTestStore.ThrowIfNeeded")); // Check proper stack trace. + + Assert.IsNotNull(ex.InnerException); // RollbackException. + + var javaEx = ex.InnerException.InnerException as JavaException; + Assert.IsNotNull(javaEx); + + CheckCustomStoreError(javaEx.InnerException); // TODO: IGNITE-4535 //cache.LocalEvict(new[] {1}); @@ -599,11 +614,9 @@ namespace Apache.Ignite.Core.Tests.Cache.Store /// </summary> private static void CheckCustomStoreError(Exception err) { - var customErr = err as CacheTestStore.CustomStoreException ?? - err.InnerException as CacheTestStore.CustomStoreException; + var customErr = err.GetBaseException() as CacheTestStore.CustomStoreException; Assert.IsNotNull(customErr); - Assert.AreEqual(customErr.Message, customErr.Details); } } http://git-wip-us.apache.org/repos/asf/ignite/blob/c396b0bc/modules/platforms/dotnet/Apache.Ignite.Core/Common/JavaException.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Common/JavaException.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Common/JavaException.cs index 1988335..e6c6f7b 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Common/JavaException.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Common/JavaException.cs @@ -62,7 +62,20 @@ namespace Apache.Ignite.Core.Common /// <param name="javaMessage">Java exception message.</param> /// <param name="stackTrace">Java stack trace.</param> public JavaException(string javaClassName, string javaMessage, string stackTrace) - : base(stackTrace ?? javaMessage) + : this(javaClassName, javaMessage, stackTrace, null) + { + // No-op. + } + + /// <summary> + /// Initializes a new instance of the <see cref="JavaException" /> class. + /// </summary> + /// <param name="javaClassName">Java exception class name.</param> + /// <param name="javaMessage">Java exception message.</param> + /// <param name="stackTrace">Java stack trace.</param> + /// <param name="cause">The cause.</param> + public JavaException(string javaClassName, string javaMessage, string stackTrace, Exception cause) + : base(stackTrace ?? javaMessage, cause) { // Send stackTrace to base ctor because it has all information, including class names and messages. // Store ClassName and Message separately for mapping purposes. http://git-wip-us.apache.org/repos/asf/ignite/blob/c396b0bc/modules/platforms/dotnet/Apache.Ignite.Core/Impl/ExceptionUtils.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/ExceptionUtils.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/ExceptionUtils.cs index dd70f5a..ebfcc28 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/ExceptionUtils.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/ExceptionUtils.cs @@ -121,9 +121,8 @@ namespace Apache.Ignite.Core.Impl public static Exception GetException(Ignite ignite, string clsName, string msg, string stackTrace, BinaryReader reader = null, Exception innerException = null) { - // Set JavaException as inner only if there is no InnerException. - if (innerException == null) - innerException = new JavaException(clsName, msg, stackTrace); + // Set JavaException as immediate inner. + innerException = new JavaException(clsName, msg, stackTrace, innerException); ExceptionFactory ctor;
