Fix null ref when expanding nodes from other providers (#1816)

* Fix null ref when expanding nodes from other providers

(cherry picked from commit 572a7b37b2a3651db5a101a8780c874c51b55b96)

* cleanup
This commit is contained in:
Charles Gagnon
2023-01-19 16:14:17 -08:00
committed by GitHub
parent 3f2d5da69a
commit ccaf5c4594
3 changed files with 19 additions and 12 deletions

View File

@@ -202,9 +202,9 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes
nodePath = path; nodePath = path;
} }
public TreeNode FindNodeByPath(string path, bool expandIfNeeded = false) public TreeNode? FindNodeByPath(string path, bool expandIfNeeded = false)
{ {
TreeNode nodeForPath = ObjectExplorerUtils.FindNode(this, node => TreeNode? nodeForPath = ObjectExplorerUtils.FindNode(this, node =>
{ {
return node.GetNodePath() == path; return node.GetNodePath() == path;
}, nodeToFilter => }, nodeToFilter =>

View File

@@ -321,7 +321,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer
ObjectExplorerTaskResult result = await RunTaskWithTimeout(task, ObjectExplorerTaskResult result = await RunTaskWithTimeout(task,
settings?.CreateSessionTimeout ?? ObjectExplorerSettings.DefaultCreateSessionTimeout); settings?.CreateSessionTimeout ?? ObjectExplorerSettings.DefaultCreateSessionTimeout);
if (result != null && !result.IsCompleted) if (result != null && !result.IsSuccessful)
{ {
cancellationTokenSource.Cancel(); cancellationTokenSource.Cancel();
SessionCreatedParameters response = new SessionCreatedParameters SessionCreatedParameters response = new SessionCreatedParameters
@@ -384,11 +384,11 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer
internal ExpandResponse QueueExpandNodeRequest(ObjectExplorerSession session, string nodePath, bool forceRefresh = false, SecurityToken? securityToken = null) internal ExpandResponse QueueExpandNodeRequest(ObjectExplorerSession session, string nodePath, bool forceRefresh = false, SecurityToken? securityToken = null)
{ {
NodeInfo[] nodes = null; NodeInfo[] nodes = null;
TreeNode node = session.Root.FindNodeByPath(nodePath); TreeNode? node = session.Root.FindNodeByPath(nodePath);
ExpandResponse response = null; ExpandResponse response = null;
// Performance Optimization for table designer to load the database model earlier based on user configuration. // Performance Optimization for table designer to load the database model earlier based on user configuration.
if (node.NodeTypeId == NodeTypes.Database && TableDesignerService.Instance.Settings.PreloadDatabaseModel) if (node?.NodeTypeId == NodeTypes.Database && TableDesignerService.Instance.Settings.PreloadDatabaseModel)
{ {
// The operation below are not blocking, but just in case, wrapping it with a task run to make sure it has no impact on the node expansion time. // The operation below are not blocking, but just in case, wrapping it with a task run to make sure it has no impact on the node expansion time.
var _ = Task.Run(() => var _ = Task.Run(() =>
@@ -604,7 +604,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer
ObjectExplorerTaskResult result = await RunTaskWithTimeout(task, ObjectExplorerTaskResult result = await RunTaskWithTimeout(task,
settings?.ExpandTimeout ?? ObjectExplorerSettings.DefaultExpandTimeout); settings?.ExpandTimeout ?? ObjectExplorerSettings.DefaultExpandTimeout);
if (result != null && !result.IsCompleted) if (result != null && !result.IsSuccessful)
{ {
cancellationTokenSource.Cancel(); cancellationTokenSource.Cancel();
ExpandResponse response = CreateExpandResponse(session, expandParams); ExpandResponse response = CreateExpandResponse(session, expandParams);
@@ -620,9 +620,10 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer
ObjectExplorerTaskResult result = new ObjectExplorerTaskResult(); ObjectExplorerTaskResult result = new ObjectExplorerTaskResult();
TimeSpan timeout = TimeSpan.FromSeconds(timeoutInSec); TimeSpan timeout = TimeSpan.FromSeconds(timeoutInSec);
await Task.WhenAny(task, Task.Delay(timeout)); await Task.WhenAny(task, Task.Delay(timeout));
result.IsCompleted = task.IsCompleted; result.IsSuccessful = task.IsCompleted;
if (task.Exception != null) if (task.Exception != null)
{ {
result.IsSuccessful = false;
result.Exception = task.Exception; result.Exception = task.Exception;
} }
else if (!task.IsCompleted) else if (!task.IsCompleted)
@@ -761,8 +762,14 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer
internal class ObjectExplorerTaskResult internal class ObjectExplorerTaskResult
{ {
public bool IsCompleted { get; set; } /// <summary>
public Exception Exception { get; set; } /// Whether the task was successfully completed. False if an error of any kind occurred during execution.
/// </summary>
public bool IsSuccessful { get; set; }
/// <summary>
/// The Exception that occurred during execution, if any.
/// </summary>
public Exception? Exception { get; set; }
} }
public void Dispose() public void Dispose()

View File

@@ -48,8 +48,8 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer
/// <param name="condition">Predicate function that accesses the tree and /// <param name="condition">Predicate function that accesses the tree and
/// determines whether to stop going further up the tree</param> /// determines whether to stop going further up the tree</param>
/// <param name="filter">Predicate function to filter the children when traversing</param> /// <param name="filter">Predicate function to filter the children when traversing</param>
/// <returns>A Tree Node that matches the condition</returns> /// <returns>A Tree Node that matches the condition, or null if no matching node could be found</returns>
public static TreeNode FindNode(TreeNode node, Predicate<TreeNode> condition, Predicate<TreeNode> filter, bool expandIfNeeded = false) public static TreeNode? FindNode(TreeNode node, Predicate<TreeNode> condition, Predicate<TreeNode> filter, bool expandIfNeeded = false)
{ {
if(node == null) if(node == null)
{ {
@@ -65,7 +65,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer
{ {
if (filter != null && filter(child)) if (filter != null && filter(child))
{ {
TreeNode childNode = FindNode(child, condition, filter, expandIfNeeded); TreeNode? childNode = FindNode(child, condition, filter, expandIfNeeded);
if (childNode != null) if (childNode != null)
{ {
return childNode; return childNode;