From df545d9c84c0fe957e49b130b5f6484015666ebe Mon Sep 17 00:00:00 2001 From: "Martin Hinshelwood nkdAgility.com" Date: Thu, 3 Oct 2024 08:21:02 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A7=20(configuration.json):=20update?= =?UTF-8?q?=20project=20name=20in=20configuration=20for=20migration=20test?= =?UTF-8?q?ing=20The=20project=20name=20in=20the=20configuration=20file=20?= =?UTF-8?q?is=20updated=20from=20"migrationTest5"=20to=20"migrationTest55"?= =?UTF-8?q?=20to=20reflect=20changes=20in=20the=20testing=20environment=20?= =?UTF-8?q?or=20project=20structure.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 📝 (MigrationTools.xml): update documentation with new commit and version details The XML documentation is updated to reflect the latest commit hash, commit date, and version tags, ensuring that the documentation is in sync with the current state of the codebase. ✨ (TfsNodeStructureTool.cs): add exception handling for project retrieval Introduces a try-catch block to handle exceptions when retrieving project information, improving robustness by catching potential configuration errors and throwing a custom `MigrationToolsException`. ✨ (MigrationToolsException.cs): create custom exception class for migration tools A new custom exception class `MigrationToolsException` is added to handle specific errors related to configuration and internal issues, providing a more structured error handling mechanism. ♻️ (Processor.cs): enhance error handling with custom exceptions Refactors the error handling in the `Processor` class to include the newly created `MigrationToolsException`, allowing for more detailed logging and error tracking based on the source of the exception. This change improves the maintainability and debuggability of the code. --- configuration.json | 2 +- docs/Reference/Generated/MigrationTools.xml | 14 ++++---- .../Tools/TfsNodeStructureTool.cs | 16 ++++++++- .../Exceptions/MigrationToolsException.cs | 25 ++++++++++++++ .../Processors/Infrastructure/Processor.cs | 33 ++++++++++++++----- 5 files changed, 73 insertions(+), 17 deletions(-) create mode 100644 src/MigrationTools/Exceptions/MigrationToolsException.cs diff --git a/configuration.json b/configuration.json index 1189db046..0aa3721c8 100644 --- a/configuration.json +++ b/configuration.json @@ -28,7 +28,7 @@ "Target": { "EndpointType": "TfsTeamProjectEndpoint", "Collection": "https://dev.azure.com/nkdagility-preview/", - "Project": "migrationTest5", + "Project": "migrationTest55", "TfsVersion": "AzureDevOps", "Authentication": { "AuthenticationMode": "AccessToken", diff --git a/docs/Reference/Generated/MigrationTools.xml b/docs/Reference/Generated/MigrationTools.xml index 1f71e8ec5..8b9e5a253 100644 --- a/docs/Reference/Generated/MigrationTools.xml +++ b/docs/Reference/Generated/MigrationTools.xml @@ -263,17 +263,17 @@ - => @"cf9e4445" + => @"23fae28b" - => @"cf9e4445856c9cb732b3bcc438d2d3fc23b3fa23" + => @"23fae28bfbd54ac74475334e64dc733a9fd28131" - => @"2024-09-23T16:40:10+01:00" + => @"2024-09-24T15:02:38+01:00" @@ -283,12 +283,12 @@ - => @"v16.0.4-Preview.4-4-gcf9e4445" + => @"v16.0.4-Preview.5-4-g23fae28b" - => @"v16.0.4-Preview.4" + => @"v16.0.4-Preview.5" @@ -323,12 +323,12 @@ - => @"Preview.4" + => @"Preview.5" - => @"-Preview.4" + => @"-Preview.5" diff --git a/src/MigrationTools.Clients.TfsObjectModel/Tools/TfsNodeStructureTool.cs b/src/MigrationTools.Clients.TfsObjectModel/Tools/TfsNodeStructureTool.cs index cfc4f8215..85ea638c6 100644 --- a/src/MigrationTools.Clients.TfsObjectModel/Tools/TfsNodeStructureTool.cs +++ b/src/MigrationTools.Clients.TfsObjectModel/Tools/TfsNodeStructureTool.cs @@ -8,12 +8,14 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Microsoft.TeamFoundation.Common; +using Microsoft.TeamFoundation.Core.WebApi; using Microsoft.TeamFoundation.Server; using Microsoft.TeamFoundation.Work.WebApi; using MigrationTools.Clients; using MigrationTools.DataContracts; using MigrationTools.Endpoints; using MigrationTools.Enrichers; +using MigrationTools.Exceptions; using MigrationTools.FieldMaps; using MigrationTools.Processors; using MigrationTools.Processors.Infrastructure; @@ -54,13 +56,14 @@ public class TfsNodeStructureTool : Tool private TfsLanguageMapOptions _sourceLanguageMaps; private TfsLanguageMapOptions _targetLanguageMaps; - private ProjectInfo _sourceProjectInfo; + private Microsoft.TeamFoundation.Server.ProjectInfo _sourceProjectInfo; private string _sourceProjectName; private NodeInfo[] _sourceRootNodes; private ICommonStructureService4 _targetCommonStructureService; private string _targetProjectName; + private Microsoft.TeamFoundation.Server.ProjectInfo _targetProjectInfo; private KeyValuePair? _lastResortRemapRule; public WorkItemMetrics workItemMetrics { get; private set; } @@ -312,6 +315,15 @@ protected void EntryForProcessorType(TfsProcessor processor) _targetCommonStructureService = processor.Target.GetService(); _targetLanguageMaps = processor.Target.Options.LanguageMaps; _targetProjectName = processor.Target.Options.Project; + try + { + _targetProjectInfo = _targetCommonStructureService.GetProjectFromName(_targetProjectName); + } + catch (ProjectException ex) + { + throw new MigrationToolsException(ex, MigrationToolsException.ExceptionSource.Configuration); + } + } } } @@ -403,6 +415,8 @@ private static string GetUserFriendlyPath(string systemNodePath) private void MigrateAllNodeStructures() { Log.LogDebug("NodeStructureEnricher.MigrateAllNodeStructures(@{areaMaps}, @{iterationMaps})", Options.Areas, Options.Iterations); + + ////////////////////////////////////////////////// ProcessCommonStructure(_sourceLanguageMaps.AreaPath, _targetLanguageMaps.AreaPath, _targetProjectName, TfsNodeStructureType.Area); ////////////////////////////////////////////////// diff --git a/src/MigrationTools/Exceptions/MigrationToolsException.cs b/src/MigrationTools/Exceptions/MigrationToolsException.cs new file mode 100644 index 000000000..34b663f02 --- /dev/null +++ b/src/MigrationTools/Exceptions/MigrationToolsException.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Elmah.Io.Client; + +namespace MigrationTools.Exceptions +{ + + + public class MigrationToolsException : Exception + { + public MigrationToolsException(Exception ex, ExceptionSource errorSource) : base(ex.Message) + { + this.ErrorSource = errorSource; + } + + public ExceptionSource ErrorSource { get; } + + public enum ExceptionSource + { + Configuration, + Internal + } + } +} diff --git a/src/MigrationTools/Processors/Infrastructure/Processor.cs b/src/MigrationTools/Processors/Infrastructure/Processor.cs index 14bafe1e6..5ac015ae8 100644 --- a/src/MigrationTools/Processors/Infrastructure/Processor.cs +++ b/src/MigrationTools/Processors/Infrastructure/Processor.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.ComponentModel.Design; using System.Diagnostics; using System.Linq; using Microsoft.Extensions.DependencyInjection; @@ -64,13 +65,13 @@ public IEndpoint GetEndpoint(string name) { throw new ArgumentException("Endpoint name cannot be null or empty", nameof(name)); } - // Assuming GetRequiredKeyedService throws an exception if the service is not found - IEndpoint endpoint = Services.GetKeyedService(name); - if (endpoint == null) - { - throw new ConfigurationValidationException( Options, ValidateOptionsResult.Fail($"The Endpoint '{name}' specified for `{this.GetType().Name}` was not found.")); - } - return endpoint; + // Assuming GetRequiredKeyedService throws an exception if the service is not found + IEndpoint endpoint = Services.GetKeyedService(name); + if (endpoint == null) + { + throw new ConfigurationValidationException(Options, ValidateOptionsResult.Fail($"The Endpoint '{name}' specified for `{this.GetType().Name}` was not found.")); + } + return endpoint; } public void Execute() @@ -113,12 +114,28 @@ public void Execute() ProcessorActivity.SetStatus(ActivityStatusCode.Error); Log.LogCritical(ex, "Validation of your configuration failed:"); } + catch (MigrationToolsException ex) + { + Status = ProcessingStatus.Failed; + ProcessorActivity.SetStatus(ActivityStatusCode.Error); + switch (ex.ErrorSource) + { + case MigrationToolsException.ExceptionSource.Configuration: + Log.LogCritical(ex, "An error occurred in the Migration Tools causing it to stop! This is likley due to a configuration issue and is not being logged remotely. You can always ask on https://github.com/nkdAgility/azure-devops-migration-tools/discussions "); + break; + case MigrationToolsException.ExceptionSource.Internal: + default: + Log.LogCritical(ex, "An error occurred in the Migration Tools causing it to stop!"); + Telemetry.TrackException(ex, ProcessorActivity.Tags); + break; + } + } catch (Exception ex) { Status = ProcessingStatus.Failed; ProcessorActivity.SetStatus(ActivityStatusCode.Error); - Telemetry.TrackException(ex, ProcessorActivity.Tags); Log.LogCritical(ex, "Error while running {MigrationContextname}", Name); + Telemetry.TrackException(ex, ProcessorActivity.Tags); } finally {