UIA Operation Abstraction library: resolve any results alredy available before a remote unhandled exception (#94)
In pr #91, new exceptions were raised by scope.Resolve such as InstructionLimitExceeded and UnhandledException. In the case of InstructionLimitExceeded, any result variables already calculated before the limit was hit will be still resolved, making them available locally. This pr now resolves any possible variables for UnhandledException as well. This now means that it is possible to track the progress of a remote operation either via remote logging for example, and even if an UnhandledException is raised from a COM call, or deliberately through a call to AbortOperationWithHresult, the variable/s holding the remote logging will still be available. This then enables the pattern of failing fast in a remote operation much nicer, as you can just abort at any point but still have access to previous variables. Tests for unhandledException have been added/updated to ensure result variables are resolved.
This commit is contained in:
Родитель
2ce5d73eb4
Коммит
d8c87fae21
|
@ -2803,7 +2803,7 @@ namespace UiaOperationAbstractionTests
|
|||
}
|
||||
|
||||
// Test that a runtime error within a remote operation causes an UnhandledRemoteException in resolve.
|
||||
TEST_METHOD(ResolveThrowsUnhandledRemoteException)
|
||||
TEST_METHOD(ResolveThrowsUnhandledRemoteExceptionForRuntimeError)
|
||||
{
|
||||
auto guard = InitializeUiaOperationAbstraction(true);
|
||||
|
||||
|
@ -2816,8 +2816,12 @@ namespace UiaOperationAbstractionTests
|
|||
UiaElement element = calc;
|
||||
|
||||
UiaArray<UiaInt> a;
|
||||
// Accessing an element of an empty array should cause an E_BOUNDS error
|
||||
a.Append(42);
|
||||
auto x = a.GetAt(0);
|
||||
// Accessing an out of bounds index of an array should raise E_BOUNDS
|
||||
auto y = a.GetAt(1);
|
||||
|
||||
scope.BindResult(x);
|
||||
|
||||
Assert::ExpectException<UnhandledRemoteException>([&]()
|
||||
{
|
||||
|
@ -2831,6 +2835,49 @@ namespace UiaOperationAbstractionTests
|
|||
throw;
|
||||
}
|
||||
});
|
||||
|
||||
// Verify that we still can access the result of a variable calculated before the exception
|
||||
Assert::AreEqual(static_cast<int>(x), 42);
|
||||
}
|
||||
|
||||
// Test that aborting an operation causes an UnhandledRemoteException in resolve,
|
||||
// and that calculated results before the abort are still available.
|
||||
TEST_METHOD(ResolveThrowsUnhandledRemoteExceptionOnAboart)
|
||||
{
|
||||
auto guard = InitializeUiaOperationAbstraction(true);
|
||||
|
||||
ModernApp app(L"Microsoft.WindowsCalculator_8wekyb3d8bbwe!App");
|
||||
app.Activate();
|
||||
auto calc = WaitForElementFocus(L"Display is 0");
|
||||
|
||||
auto scope = UiaOperationScope::StartNew();
|
||||
|
||||
UiaElement element = calc;
|
||||
|
||||
UiaArray<UiaInt> a;
|
||||
a.Append(42);
|
||||
auto x = a.GetAt(0);
|
||||
// Aborting a remote operation should result in an Unhandled exception
|
||||
const HRESULT myError = -1234;
|
||||
scope.AbortOperationWithHresult(myError);
|
||||
|
||||
scope.BindResult(x);
|
||||
|
||||
Assert::ExpectException<UnhandledRemoteException>([&]()
|
||||
{
|
||||
try
|
||||
{
|
||||
scope.Resolve();
|
||||
}
|
||||
catch(winrt::hresult_error& e)
|
||||
{
|
||||
Assert::AreEqual(myError, static_cast<HRESULT>(e.code()));
|
||||
throw;
|
||||
}
|
||||
});
|
||||
|
||||
// Verify that we still can access the result of a variable calculated before the exception
|
||||
Assert::AreEqual(static_cast<int>(x), 42);
|
||||
}
|
||||
|
||||
// Test that an execution failure within a remote operation causes an ExecutionFailureException in resolve.
|
||||
|
|
|
@ -2370,11 +2370,12 @@ namespace UiaOperationAbstraction
|
|||
}
|
||||
|
||||
// Fetch bound results on success, but also
|
||||
// instruction limit exceeded,
|
||||
// instruction limit exceeded and UnhandledException,
|
||||
// As we know certainly some of the remote operation did execute.
|
||||
if (
|
||||
status == winrt::Windows::UI::UIAutomation::Core::AutomationRemoteOperationStatus::Success
|
||||
|| status == winrt::Windows::UI::UIAutomation::Core::AutomationRemoteOperationStatus::InstructionLimitExceeded
|
||||
|| status == winrt::Windows::UI::UIAutomation::Core::AutomationRemoteOperationStatus::UnhandledException
|
||||
)
|
||||
{
|
||||
for (auto& resolver : remoteOperationResolvers)
|
||||
|
|
Загрузка…
Ссылка в новой задаче