Skip to content

Commit 179c864

Browse files
authored
Handle possible null ref in error handler (microsoft#819)
I have a dump that throws access violation exception in native code and the test run fails with: `An exception occurred while invoking executor 'executor://mstestadapter/v2': Object reference not set to an instance of an object.` I looked through the code and the only way I can get this result is when ex would be null in the handler. Otherwise it fails with different error, either from the asserts in the `StackTraceHelper` methods or in upstream error handlers.
1 parent e0289e8 commit 179c864

File tree

4 files changed

+35
-7
lines changed

4 files changed

+35
-7
lines changed

src/Adapter/MSTest.CoreAdapter/Execution/TestMethodInfo.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -717,11 +717,27 @@ private object CreateTestClassInstance(TestResult result)
717717
}
718718
catch (Exception ex)
719719
{
720+
if (ex == null)
721+
{
722+
// It seems that ex can be null in some rare cases when initialization fails in native code.
723+
// Get our own exception with a stack trace to satisfy GetStackTraceInformation.
724+
try
725+
{
726+
throw new InvalidOperationException(Resource.UTA_UserCodeThrewNullValueException);
727+
}
728+
catch (Exception exception)
729+
{
730+
ex = exception;
731+
}
732+
}
733+
720734
// In most cases, exception will be TargetInvocationException with real exception wrapped
721-
// in the InnerException; or user code throws an exception
735+
// in the InnerException; or user code throws an exception.
736+
// It also seems that in rare cases the ex can be null.
722737
var actualException = ex.InnerException ?? ex;
723738
var exceptionMessage = StackTraceHelper.GetExceptionMessage(actualException);
724739
var stackTraceInfo = StackTraceHelper.GetStackTraceInformation(actualException);
740+
725741
var errorMessage = string.Format(
726742
CultureInfo.CurrentCulture,
727743
Resource.UTA_InstanceCreationError,

src/Adapter/MSTest.CoreAdapter/Execution/TestMethodRunner.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ internal UnitTestResult[] RunTestMethod()
270270
{
271271
testResults = new[]
272272
{
273-
new UTF.TestResult() { TestFailureException = new Exception(string.Format(CultureInfo.CurrentCulture, Resource.UTA_ExecuteThrewException, ex.Message), ex) }
273+
new UTF.TestResult() { TestFailureException = new Exception(string.Format(CultureInfo.CurrentCulture, Resource.UTA_ExecuteThrewException, ex?.Message, ex?.StackTrace), ex) }
274274
};
275275
}
276276

@@ -324,7 +324,7 @@ internal UnitTestResult[] RunTestMethod()
324324
{
325325
testResults = new[]
326326
{
327-
new UTF.TestResult() { TestFailureException = new Exception(string.Format(CultureInfo.CurrentCulture, Resource.UTA_ExecuteThrewException, ex.Message), ex) }
327+
new UTF.TestResult() { TestFailureException = new Exception(string.Format(CultureInfo.CurrentCulture, Resource.UTA_ExecuteThrewException, ex?.Message, ex?.StackTrace), ex) }
328328
};
329329
}
330330

@@ -346,7 +346,7 @@ internal UnitTestResult[] RunTestMethod()
346346
}
347347
catch (Exception ex)
348348
{
349-
results.Add(new UTF.TestResult() { TestFailureException = new Exception(string.Format(CultureInfo.CurrentCulture, Resource.UTA_ExecuteThrewException, ex.Message), ex) });
349+
results.Add(new UTF.TestResult() { TestFailureException = new Exception(string.Format(CultureInfo.CurrentCulture, Resource.UTA_ExecuteThrewException, ex?.Message, ex?.StackTrace), ex) });
350350
}
351351
}
352352
}

src/Adapter/MSTest.CoreAdapter/Resources/Resource.Designer.cs

Lines changed: 11 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Adapter/MSTest.CoreAdapter/Resources/Resource.resx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ Error: {1}</value>
209209
<value>Class Initialization method {0}.{1} threw exception. {2}: {3}.</value>
210210
</data>
211211
<data name="UTA_ExecuteThrewException" xml:space="preserve">
212-
<value>Exception thrown while executing test. If using extension of TestMethodAttribute then please contact vendor. Error message: {0}</value>
212+
<value>Exception thrown while executing test. If using extension of TestMethodAttribute then please contact vendor. Error message: {0}, Stack trace: {1}</value>
213213
</data>
214214
<data name="UTA_NoTestResult" xml:space="preserve">
215215
<value>Error in executing test. No result returned by extension. If using extension of TestMethodAttribute then please contact vendor.</value>
@@ -320,4 +320,7 @@ Error: {1}</value>
320320
<data name="Execution_Test_Cancelled" xml:space="preserve">
321321
<value>Test '{0}' execution has been aborted.</value>
322322
</data>
323+
<data name="UTA_UserCodeThrewNullValueException" xml:space="preserve">
324+
<value>The called code threw an exception that was caught, but the exception value was null</value>
325+
</data>
323326
</root>

0 commit comments

Comments
 (0)