Particular / ServiceControl

Backend for ServiceInsight and ServicePulse

Home Page:https://docs.particular.net/servicecontrol/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

New-ServiceControlInstance not returning/bubbling errors correctly

TraGicCode opened this issue · comments

I'm currently trying to automate the installation and management of Service Control instances and notice that it seems the New-ServiceControlInstance Cmdlet is not returning errors back to the caller (my powershell script) correctly causing me to be unable to determine if the new instance was created successfully or failed because of errors or prequisites.

When running

PS C:\Users\vagrant> New-ServiceControlInstance -Name Test -Transport MSMQ -InstallPath c:\install -DBPath c:\db -LogPath c:\logs -Port 12 -AuditRetentionPeriod "15.0:0:0" -ErrorRetentionPeriod "15.0:0:0" -ForwardAuditMessages -DatabaseMaintenancePort 2 -ErrorVariable MyError

I see an error stating MSMQ is not installed as shown below

WARNING: HostName set to default value 'localhost'
WARNING: AuditQueue set to default value 'audit'
WARNING: ErrorQueue set to default value 'error'
WARNING: ServiceAccount set to default value 'LocalSystem'
WARNING: AuditLogQueue set to default value 'audit.log'
VERBOSE: Installing Service Control instance...
MSMQ Service is not installed
Each of the queue names specified for a instance should be unique
PS C:\Users\vagrant>

By checking my error variable named MyError that was passed into the cmdlet is always returned as an ArrayList of count 0.

I wonder if this is because we pass null into the ErrorId parameter of the ErrorRecord.

I'll dig into it.

Hey @WilliamBZA ,

I believe it's related to not throwing errors when they occur from inside the Add Function on the UnattendServiceControlInstaller class. It looks like when errors occur they are simply be logged.

public bool Add(ServiceControlNewInstance details, Func<PathInfo, bool> promptToProceed)
{
ZipInfo.ValidateZip();
var checkLicenseResult = CheckLicenseIsValid();
if (!checkLicenseResult.Valid)
{
logger.Error($"Install aborted - {checkLicenseResult.Message}");
return false;
}
var instanceInstaller = details;
instanceInstaller.ReportCard = new ReportCard();
instanceInstaller.Version = ZipInfo.Version;
//Validation
instanceInstaller.Validate(promptToProceed);
if (instanceInstaller.ReportCard.HasErrors)
{
foreach (var error in instanceInstaller.ReportCard.Errors)
{
logger.Error(error);
}
return false;
}
try
{
instanceInstaller.CopyFiles(ZipInfo.FilePath);
instanceInstaller.WriteConfigurationFile();
instanceInstaller.RegisterUrlAcl();
instanceInstaller.SetupInstance();
instanceInstaller.RegisterService();
foreach (var warning in instanceInstaller.ReportCard.Warnings)
{
logger.Warn(warning);
}
if (instanceInstaller.ReportCard.HasErrors)
{
foreach (var error in instanceInstaller.ReportCard.Errors)
{
logger.Error(error);
}
return false;
}
}
catch (Exception ex)
{
logger.Error(ex.Message);
return false;
}
//Post Installation
var instance = InstanceFinder.FindServiceControlInstance(instanceInstaller.Name);
if (!instance.TryStartService())
{
logger.Warn("The service failed to start");
}
return true;
}

If you can verify this is the case i think the signature of the function should remove the boolean and instead throw exceptions instead on errors.