Skip to content

Commit

Permalink
Merge pull request #2080 from robertbasti/main
Browse files Browse the repository at this point in the history
Null reference exceptions, empty collections #2042
  • Loading branch information
robertbasti authored Oct 16, 2023
2 parents e31d7f1 + fd37fb2 commit 20d8657
Show file tree
Hide file tree
Showing 16 changed files with 49 additions and 36 deletions.
4 changes: 2 additions & 2 deletions Src/Witsml/Extensions/WitsmlLogExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ public static string GetStartIndexAsString(this WitsmlLog witsmlLog)
{
return witsmlLog.StartIndex == null && string.IsNullOrEmpty(witsmlLog.StartDateTimeIndex)
? null
: witsmlLog.IndexType.Equals(WitsmlLog.WITSML_INDEX_TYPE_MD, System.StringComparison.Ordinal) ? witsmlLog.StartIndex != null ? witsmlLog.StartIndex.ToString() : "" : witsmlLog.StartDateTimeIndex;
: string.Equals(witsmlLog.IndexType, WitsmlLog.WITSML_INDEX_TYPE_MD, System.StringComparison.Ordinal) ? witsmlLog.StartIndex != null ? witsmlLog.StartIndex.ToString() : "" : witsmlLog.StartDateTimeIndex;
}

public static string GetEndIndexAsString(this WitsmlLog witsmlLog)
{
return witsmlLog.EndIndex == null && string.IsNullOrEmpty(witsmlLog.EndDateTimeIndex)
? null
: witsmlLog.IndexType.Equals(WitsmlLog.WITSML_INDEX_TYPE_MD, System.StringComparison.Ordinal) ? witsmlLog.EndIndex != null ? witsmlLog.EndIndex.ToString() : "" : witsmlLog.EndDateTimeIndex;
: string.Equals(witsmlLog.IndexType, WitsmlLog.WITSML_INDEX_TYPE_MD, System.StringComparison.Ordinal) ? witsmlLog.EndIndex != null ? witsmlLog.EndIndex.ToString() : "" : witsmlLog.EndDateTimeIndex;
}


Expand Down
2 changes: 1 addition & 1 deletion Src/WitsmlExplorer.Api/HttpHandlers/ObjectHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public static async Task<IResult> GetObjectsIdOnly(string wellUid, string wellbo
public static async Task<IResult> GetObjectIdOnly(string wellUid, string wellboreUid, string objectUid, EntityType objectType, IObjectService objectService)
{
IEnumerable<ObjectOnWellbore> result = await objectService.GetObjectIdOnly(wellUid, wellboreUid, objectUid, objectType);
return TypedResults.Ok(result?.First());
return TypedResults.Ok(result?.FirstOrDefault());
}

[Produces(typeof(Dictionary<EntityType, int>))]
Expand Down
6 changes: 3 additions & 3 deletions Src/WitsmlExplorer.Api/Query/TrajectoryQueries.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,17 +127,17 @@ public static WitsmlTrajectories UpdateTrajectoryStation(TrajectoryStation traje
TypeTrajStation = trajectoryStation.TypeTrajStation
};

if (!trajectoryStation.Tvd.Equals(null))
if (trajectoryStation.Tvd != null)
{
ts.Tvd = new WitsmlWellVerticalDepthCoord { Uom = trajectoryStation.Tvd.Uom, Value = trajectoryStation.Tvd.Value.ToString(CultureInfo.InvariantCulture) };
}

if (!trajectoryStation.Incl.Equals(null))
if (trajectoryStation.Incl != null)
{
ts.Incl = new WitsmlPlaneAngleMeasure { Uom = trajectoryStation.Incl.Uom, Value = trajectoryStation.Incl.Value.ToString(CultureInfo.InvariantCulture) };
}

if (!trajectoryStation.Azi.Equals(null))
if (trajectoryStation.Azi != null)
{
ts.Azi = new WitsmlPlaneAngleMeasure { Uom = trajectoryStation.Azi.Uom, Value = trajectoryStation.Azi.Value.ToString(CultureInfo.InvariantCulture) };
}
Expand Down
2 changes: 1 addition & 1 deletion Src/WitsmlExplorer.Api/Services/CapService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public CapService(IWitsmlClientProvider witsmlClientProvider) : base(witsmlClien

public async Task<WitsmlServerCapabilities> GetCap()
{
return (await _witsmlClient.GetCap()).ServerCapabilities.FirstOrDefault();
return (await _witsmlClient.GetCap()).ServerCapabilities?.FirstOrDefault();
}
}
}
2 changes: 1 addition & 1 deletion Src/WitsmlExplorer.Api/Services/CredentialsService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ public ServerCredentials GetCredentials(IEssentialHeaders eh, string server, str
if (creds == null && _useOAuth2)
{
creds = GetSystemCredentialsByToken(eh.GetBearerToken(), new Uri(server)).Result;
if (creds.IsCredsNullOrEmpty() || !creds.UserId.Equals(username, StringComparison.Ordinal))
if (creds.IsCredsNullOrEmpty() || !string.Equals(creds.UserId, username, StringComparison.Ordinal))
{
return null;
}
Expand Down
4 changes: 2 additions & 2 deletions Src/WitsmlExplorer.Api/Services/ObjectService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ public async Task<IEnumerable<ObjectSearchResult>> GetObjectsWithParamByType(Ent
IWitsmlObjectList capabilityQuery = (IWitsmlObjectList)EntityTypeHelper.ToObjectOnWellbore(objectType).AsSingletonWitsmlList();
IWitsmlObjectList capabilityResult = await _witsmlClient.GetFromStoreNullableAsync(capabilityQuery, new OptionsIn(RequestObjectSelectionCapability: true));

WitsmlObjectOnWellbore capabilities = capabilityResult.Objects.First();
bool isCapable = capabilities.GetType().GetProperty(objectProperty.CapitalizeFirstLetter())?.GetValue(capabilities, null) != null;
WitsmlObjectOnWellbore capabilities = capabilityResult?.Objects?.FirstOrDefault();
bool isCapable = capabilities?.GetType().GetProperty(objectProperty.CapitalizeFirstLetter())?.GetValue(capabilities, null) != null;
if (!isCapable)
{
throw new Middleware.WitsmlUnsupportedCapabilityException($"The server does not support to select {objectProperty} for a {objectType}.");
Expand Down
2 changes: 1 addition & 1 deletion Src/WitsmlExplorer.Api/Services/TubularService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public async Task<IEnumerable<TubularComponent>> GetTubularComponents(string wel
WitsmlTubular witsmlTubular = result.Tubulars.FirstOrDefault();
return witsmlTubular == null
? null
: (IEnumerable<TubularComponent>)witsmlTubular.TubularComponents.Select(tComponent => new TubularComponent
: (IEnumerable<TubularComponent>)witsmlTubular.TubularComponents?.Select(tComponent => new TubularComponent
{
Uid = tComponent.Uid,
Sequence = tComponent.Sequence,
Expand Down
2 changes: 1 addition & 1 deletion Src/WitsmlExplorer.Api/Workers/AnalyzeGapWorker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ private AnalyzeGapReport GetGapReport(IList<string> selectedMnemonics, IList<Ana
private IEnumerable<AnalyzeGapReportItem> GetAnalyzeGapReportItem(string mnemonic, IList<Index> inputIndexList, Index requestedGapSize, bool isLogIncreasing)
{
List<AnalyzeGapReportItem> gapValues = new();
Index lastValueIndex = inputIndexList.FirstOrDefault();
Index lastValueIndex = inputIndexList?.FirstOrDefault();

if (lastValueIndex == null) return gapValues;

Expand Down
25 changes: 19 additions & 6 deletions Src/WitsmlExplorer.Api/Workers/CheckLogHeaderWorker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Threading.Tasks;

using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;

using Witsml.Data;
using Witsml.ServiceReference;
Expand Down Expand Up @@ -74,7 +75,7 @@ public CheckLogHeaderWorker(ILogger<CheckLogHeaderJob> logger, IWitsmlClientProv
{
WitsmlLogs headerQuery = LogQueries.GetLogHeaderIndexes(wellUid, wellboreUid, logUid);
WitsmlLogs headerResult = await GetTargetWitsmlClientOrThrow().GetFromStoreNullableAsync(headerQuery, new OptionsIn(ReturnElements.Requested));
if (headerResult == null)
if (headerResult == null || headerResult.Objects.IsNullOrEmpty())
{
return null;
}
Expand All @@ -91,18 +92,30 @@ public CheckLogHeaderWorker(ILogger<CheckLogHeaderJob> logger, IWitsmlClientProv
WitsmlLogs dataQuery = LogQueries.GetLogContent(wellUid, wellboreUid, logUid, indexType, Enumerable.Empty<string>(), null, null);
WitsmlLogs dataStartResult = await GetTargetWitsmlClientOrThrow().GetFromStoreNullableAsync(dataQuery, new OptionsIn(ReturnElements.DataOnly, MaxReturnNodes: 1));
WitsmlLogs dataEndResult = await GetTargetWitsmlClientOrThrow().GetFromStoreNullableAsync(dataQuery, new OptionsIn(ReturnElements.DataOnly, RequestLatestValues: 1));
if (dataStartResult.Objects.IsNullOrEmpty() || dataEndResult.Objects.IsNullOrEmpty())
{
return null;
}
WitsmlLog dataStartResultLog = (WitsmlLog)dataStartResult.Objects.First();
WitsmlLog dataEndResultLog = (WitsmlLog)dataEndResult.Objects.First();
if (dataStartResultLog.LogData == null || dataEndResultLog.LogData == null)
{
return null;
}
IEnumerable<IEnumerable<string>> endResultLogData = dataEndResultLog.LogData.Data.Select(data => data.Data.Split(","));
string[] startResultLogData = dataStartResultLog.LogData.Data.First().Data.Split(",");
IEnumerable<IEnumerable<string>> endResultLogData = dataEndResultLog.LogData.Data?.Select(data => data.Data.Split(","));
string[] startResultLogData = dataStartResultLog.LogData.Data?.FirstOrDefault()?.Data.Split(",");
if (startResultLogData.IsNullOrEmpty() || endResultLogData.IsNullOrEmpty())
{
return null;
}
IEnumerable<string> dataStartIndexes = startResultLogData.Select(data => data == "" ? "" : startResultLogData[0]);
IEnumerable<string> dataEndIndexes = ExtractColumnIndexes(endResultLogData);
string[] startMnemonics = dataStartResultLog.LogData.MnemonicList.Split(",");
string[] endMnemonics = dataEndResultLog.LogData.MnemonicList.Split(",");
string[] startMnemonics = dataStartResultLog.LogData.MnemonicList?.Split(",");
string[] endMnemonics = dataEndResultLog.LogData.MnemonicList?.Split(",");
if (startMnemonics == null || endMnemonics == null)
{
return null;
}
Dictionary<string, string> dataStartValues = dataStartIndexes.Select((value, index) => new { mnemonic = startMnemonics[index], value }).ToDictionary(d => d.mnemonic, d => d.value);
Dictionary<string, string> dataEndValues = dataEndIndexes.Where(value => !string.IsNullOrEmpty(value)).Select((value, index) => new { mnemonic = endMnemonics[index], value }).ToDictionary(d => d.mnemonic, d => d.value);

Expand All @@ -123,7 +136,7 @@ private async Task<Dictionary<string, string>> AddStartIndexForMissingMnemonics(
List<Task<WitsmlLogs>> missingDataResults = missingIndexQueries.Select(query => GetTargetWitsmlClientOrThrow().GetFromStoreNullableAsync(query, new OptionsIn(ReturnElements.DataOnly, MaxReturnNodes: 1))).ToList();
await Task.WhenAll(missingDataResults);
IEnumerable<WitsmlLog> missingLogs = missingDataResults.Select(r => (WitsmlLog)r.Result.Objects.First());
IEnumerable<string> missingDataIndexes = missingLogs.Select(l => l.LogData.Data?.FirstOrDefault()?.Data?.Split(",")?[0] ?? "");
IEnumerable<string> missingDataIndexes = missingLogs.Select(l => l.LogData?.Data?.FirstOrDefault()?.Data?.Split(",")?[0] ?? "");
// Insert the indexes from the missing mnemonics to the original dict.
missingDataIndexes
.Select((value, index) => new { mnemonic = missingMnemonics[index], value })
Expand Down
14 changes: 7 additions & 7 deletions Src/WitsmlExplorer.Api/Workers/Copy/CopyComponentsWorker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,23 +62,23 @@ public CopyComponentsWorker(ILogger<CopyComponentsJob> logger, IWitsmlClientProv

string[] toCopyUids = job.Source.ComponentUids;
IWitsmlObjectList sourceQuery = ObjectQueries.GetWitsmlObjectByReference(job.Source.Parent, _componentType.ToParentType());
ObjectQueries.SetComponents(sourceQuery.Objects.First(), _componentType, toCopyUids);
ObjectQueries.SetComponents(sourceQuery.Objects?.FirstOrDefault(), _componentType, toCopyUids);
IWitsmlObjectList source = await GetSourceWitsmlClientOrThrow().GetFromStoreNullableAsync(sourceQuery, new OptionsIn(ReturnElements.All));
if (source == null)
{
string reason = $"Unable to fetch {_componentType.ToParentType()} with uid {sourceQuery.Objects.First().Uid}.";
string reason = $"Unable to fetch {_componentType.ToParentType()} with uid {sourceQuery.Objects?.FirstOrDefault()?.Uid}.";
return LogErrorAndReturnResult(reason);
}

IEnumerable<string> sourceComponentUids = ObjectQueries.GetComponentUids(source.Objects.First(), _componentType);
IEnumerable<string> sourceComponentUids = ObjectQueries.GetComponentUids(source.Objects?.FirstOrDefault(), _componentType);
IEnumerable<string> missingUids = toCopyUids.Except(sourceComponentUids);
if (missingUids.Any())
{
string reason = $"Could not retrieve some {_componentType.ToPluralLowercase()}, missing uids: {string.Join(", ", missingUids)}.";
return LogErrorAndReturnResult(reason);
}

WitsmlObjectOnWellbore updateTargetQuery = ObjectQueries.CopyComponents(source.Objects.First(), _componentType, job.Target, toCopyUids);
WitsmlObjectOnWellbore updateTargetQuery = ObjectQueries.CopyComponents(source.Objects?.FirstOrDefault(), _componentType, job.Target, toCopyUids);
QueryResult copyResult = await targetClient.UpdateInStoreAsync(updateTargetQuery.AsSingletonWitsmlList());
if (!copyResult.IsSuccessful)
{
Expand All @@ -95,17 +95,17 @@ public CopyComponentsWorker(ILogger<CopyComponentsJob> logger, IWitsmlClientProv
private async Task<string> VerifyTarget()
{
IWitsmlObjectList targetQuery = ObjectQueries.GetWitsmlObjectByReference(_job.Target, _componentType.ToParentType());
ObjectQueries.SetComponents(targetQuery.Objects.First(), _componentType, _job.Source.ComponentUids);
ObjectQueries.SetComponents(targetQuery?.Objects?.FirstOrDefault(), _componentType, _job.Source.ComponentUids);
IWitsmlObjectList target = await GetTargetWitsmlClientOrThrow().GetFromStoreNullableAsync(targetQuery, new OptionsIn(ReturnElements.Requested));
if (target == null)
{
return $"Target {_componentType.ToParentType()} with uid {targetQuery.Objects.First().Uid} could not be fetched.";
return $"Target {_componentType.ToParentType()} with uid {targetQuery?.Objects?.FirstOrDefault()?.Uid} could not be fetched.";
}
if (!target.Objects.Any()) //if no uids to copy are present in the target then no object is returned
{
return null;
}
IEnumerable<string> targetComponentUids = ObjectQueries.GetComponentUids(target.Objects.First(), _componentType);
IEnumerable<string> targetComponentUids = ObjectQueries.GetComponentUids(target.Objects.FirstOrDefault(), _componentType);
IEnumerable<string> conflictingUids = targetComponentUids.Intersect(_job.Source.ComponentUids);
if (conflictingUids.Any())
{
Expand Down
4 changes: 2 additions & 2 deletions Src/WitsmlExplorer.Api/Workers/Copy/CopyUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,10 @@ public CopyUtils(ILogger<CopyUtils> logger)
}
}).ToList());

string successString = successUids.Count > 0 ? $"Copied {queries.First().GetType().Name}s: {string.Join(", ", successUids)}." : "";
string successString = successUids.Count > 0 ? $"Copied {queries.FirstOrDefault()?.GetType().Name}s: {string.Join(", ", successUids)}." : "";
return !error
? (new WorkerResult(witsmlClient.GetServerHostname(), true, successString), refreshAction)
: (new WorkerResult(witsmlClient.GetServerHostname(), false, $"{successString} Failed to copy some {queries.First().GetType().Name}s", errorReason, errorEntity), successUids.Count > 0 ? refreshAction : null);
: (new WorkerResult(witsmlClient.GetServerHostname(), false, $"{successString} Failed to copy some {queries.First()?.GetType().Name}s", errorReason, errorEntity), successUids.Count > 0 ? refreshAction : null);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public DeleteCurveValuesWorker(ILogger<DeleteCurveValuesJob> logger, IWitsmlClie
wellUid,
wellboreUid,
logUid,
query.Logs.First().LogCurveInfo.First().Mnemonic);
query.Logs.FirstOrDefault()?.LogCurveInfo?.FirstOrDefault()?.Mnemonic);
}
else
{
Expand Down
8 changes: 4 additions & 4 deletions Src/WitsmlExplorer.Api/Workers/Delete/DeleteObjectsWorker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ public DeleteObjectsWorker(ILogger<DeleteObjectsJob> logger, IWitsmlClientProvid
private async Task<(WorkerResult, RefreshAction)> DeleteObjectsOnWellbore(IEnumerable<WitsmlObjectOnWellbore> queries, RefreshAction refreshAction)
{
IWitsmlClient witsmlClient = GetTargetWitsmlClientOrThrow();
string uidWell = queries.First().UidWell;
string uidWellbore = queries.First().UidWellbore;
string uidWell = queries.FirstOrDefault()?.UidWell;
string uidWellbore = queries.FirstOrDefault()?.UidWellbore;

bool error = false;
List<string> successUids = new();
Expand Down Expand Up @@ -79,10 +79,10 @@ await Task.WhenAll(queries.Select(async (query) =>
}
}).ToList());

string successString = successUids.Count > 0 ? $"Deleted {queries.First().GetType().Name}s: {string.Join(", ", successUids)}." : "";
string successString = successUids.Count > 0 ? $"Deleted {queries.FirstOrDefault()?.GetType().Name}s: {string.Join(", ", successUids)}." : "";
return !error
? (new WorkerResult(witsmlClient.GetServerHostname(), true, successString), refreshAction)
: (new WorkerResult(witsmlClient.GetServerHostname(), false, $"{successString} Failed to delete some {queries.First().GetType().Name}s", errorReason, null), successUids.Count > 0 ? refreshAction : null);
: (new WorkerResult(witsmlClient.GetServerHostname(), false, $"{successString} Failed to delete some {queries.FirstOrDefault()?.GetType().Name}s", errorReason, null), successUids.Count > 0 ? refreshAction : null);
}
}
}
2 changes: 1 addition & 1 deletion Src/WitsmlExplorer.Api/Workers/ImportLogDataWorker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public ImportLogDataWorker(ILogger<ImportLogDataJob> logger, IWitsmlClientProvid
}

WitsmlLogs addMnemonicsQuery = CreateAddMnemonicsQuery(job, witsmlLog);
if (addMnemonicsQuery.Logs.FirstOrDefault().LogCurveInfo.Count > 0)
if (addMnemonicsQuery.Logs.FirstOrDefault().LogCurveInfo?.Count > 0)
{
QueryResult addMnemonicsResult = await GetTargetWitsmlClientOrThrow().UpdateInStoreAsync(addMnemonicsQuery);
if (addMnemonicsResult.IsSuccessful)
Expand Down
2 changes: 1 addition & 1 deletion Src/WitsmlExplorer.Api/Workers/RenameMnemonicWorker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ private static void Verify(RenameMnemonicJob job)
{
throw new InvalidOperationException("Empty name given when trying to rename a mnemonic. Make sure valid names are given");
}
else if (job.Mnemonic.Equals(job.NewMnemonic, StringComparison.OrdinalIgnoreCase))
else if (string.Equals(job.Mnemonic, job.NewMnemonic, StringComparison.OrdinalIgnoreCase))
{
throw new InvalidOperationException("Cannot rename a mnemonic to the same name it already has. Make sure new mnemonic is a unique name");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ private async IAsyncEnumerable<WitsmlWellbore> GetActiveWellbores()
{
UidWell = groupedResult.UidWell,
Uid = groupedResult.UidWellbore,
NameWell = groupedResult.Logs.First().NameWell,
Name = groupedResult.Logs.First().NameWellbore
NameWell = groupedResult.Logs.FirstOrDefault()?.NameWell,
Name = groupedResult.Logs.FirstOrDefault()?.NameWellbore
};
}
}
Expand Down

0 comments on commit 20d8657

Please sign in to comment.