Skip to content

Commit

Permalink
🛠 errors in calls to Jira server now rethrown enriched with call argu…
Browse files Browse the repository at this point in the history
…ments
  • Loading branch information
nop77svk committed Jul 11, 2024
1 parent 5b2607a commit 26506f7
Show file tree
Hide file tree
Showing 9 changed files with 225 additions and 8 deletions.
4 changes: 2 additions & 2 deletions jwl.infra/UriQueryBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ public UriQueryBuilder Add(string? key, string? value)
}

public override string ToString() => this.Any()
? string.Join('&', this
? '?' + string.Join('&', this
.Where(x => !string.IsNullOrEmpty(x.Key) || !string.IsNullOrEmpty(x.Value))
.Select(x => Uri.EscapeDataString(x.Key ?? string.Empty) + "=" + Uri.EscapeDataString(x.Value ?? string.Empty))
.Prepend("?"))
)
: string.Empty;

public static implicit operator string(UriQueryBuilder self) => self.ToString();
Expand Down
24 changes: 24 additions & 0 deletions jwl.jira/Exceptions/AddWorkLogException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
namespace jwl.jira.Exceptions;

internal class AddWorkLogException
: JiraIssueSpecificException
{
public DateTime Moment { get; }
public int TimeSpentSeconds { get; }
public string? Activity { get; init; }
public string? Comment { get; init; }

public AddWorkLogException(string issueKey, DateTime moment, int timeSpentSeconds)
: base(issueKey, $"Error adding {timeSpentSeconds} seconds on issue {issueKey} at {moment}")
{
Moment = moment;
TimeSpentSeconds = timeSpentSeconds;
}

public AddWorkLogException(string issueKey, DateTime moment, int timeSpentSeconds, Exception innerException)
: base(issueKey, $"Error adding {timeSpentSeconds} seconds on issue {issueKey} at {moment}", innerException)
{
Moment = moment;
TimeSpentSeconds = timeSpentSeconds;
}
}
23 changes: 23 additions & 0 deletions jwl.jira/Exceptions/DeleteWorklogException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
namespace jwl.jira.Exceptions;

[Serializable]
internal class DeleteWorklogException
: JiraIssueSpecificException
{
public long IssueId { get; }
public long WorklogId { get; }

public DeleteWorklogException(long issueId, long worklogId)
: base($"ID {issueId}", $"Error deleting worklog ID {worklogId} on issue ID {issueId}")
{
IssueId = issueId;
WorklogId = worklogId;
}

public DeleteWorklogException(long issueId, long worklogId, Exception innerException)
: base($"ID {issueId}", $"Error deleting worklog ID {worklogId} on issue ID {issueId}", innerException)
{
IssueId = issueId;
WorklogId = worklogId;
}
}
24 changes: 24 additions & 0 deletions jwl.jira/Exceptions/GetIssueWorkLogsException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
namespace jwl.jira.Exceptions;

using System;

public class GetIssueWorkLogsException
: JiraIssueSpecificException
{
public DateTime DateFrom { get; }
public DateTime DateTo { get; }

public GetIssueWorkLogsException(string issueKey, DateTime dateFrom, DateTime dateTo)
: base(issueKey, $"Error retrieving worklogs for {issueKey} and timestamp range from {dateFrom} to {dateTo}")
{
DateFrom = dateFrom;
DateTo = dateTo;
}

public GetIssueWorkLogsException(string issueKey, DateTime dateFrom, DateTime dateTo, Exception innerException)
: base(issueKey, $"Error retrieving worklogs for issue \"{issueKey}\" and period from {dateFrom} to {dateTo}", innerException)
{
DateFrom = dateFrom;
DateTo = dateTo;
}
}
21 changes: 21 additions & 0 deletions jwl.jira/Exceptions/JiraClientException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
namespace jwl.jira.Exceptions;

using System;

public class JiraClientException
: ApplicationException
{
public JiraClientException()
{
}

public JiraClientException(string? message)
: base(message)
{
}

public JiraClientException(string? message, Exception? innerException)
: base(message, innerException)
{
}
}
31 changes: 31 additions & 0 deletions jwl.jira/Exceptions/JiraIssueSpecificException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
namespace jwl.jira.Exceptions;

public class JiraIssueSpecificException
: JiraClientException
{
public string? IssueKey { get; }

public JiraIssueSpecificException(string issueKey)
: base($"Error on Jira issue {issueKey}")
{
IssueKey = issueKey;
}

public JiraIssueSpecificException(string issueKey, string message)
: base(message)
{
IssueKey = issueKey;
}

public JiraIssueSpecificException(string issueKey, Exception innerException)
: base($"Error on Jira issue {issueKey}", innerException)
{
IssueKey = issueKey;
}

public JiraIssueSpecificException(string issueKey, string message, Exception innerException)
: base(message, innerException)
{
IssueKey = issueKey;
}
}
27 changes: 27 additions & 0 deletions jwl.jira/Exceptions/UpdateWorklogException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
namespace jwl.jira.Exceptions;

public class UpdateWorklogException
: JiraIssueSpecificException
{
public long WorklogId { get; }
public DateTime Moment { get; }
public int TimeSpentSeconds { get; }
public string? Activity { get; init; }
public string? Comment { get; init; }

public UpdateWorklogException(string issueKey, long worklogId, DateTime moment, int timeSpentSeconds)
: base(issueKey, $"Error updating worklog ID {worklogId} with {timeSpentSeconds} seconds on issue {issueKey} at {moment}")
{
WorklogId = worklogId;
Moment = moment;
TimeSpentSeconds = timeSpentSeconds;
}

public UpdateWorklogException(string issueKey, long worklogId, DateTime moment, int timeSpentSeconds, Exception innerException)
: base(issueKey, $"Error updating worklog ID {worklogId} with {timeSpentSeconds} seconds on issue {issueKey} at {moment}", innerException)
{
WorklogId = worklogId;
Moment = moment;
TimeSpentSeconds = timeSpentSeconds;
}
}
13 changes: 12 additions & 1 deletion jwl.jira/Flavours/JiraWithICTimePluginApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Xml.Serialization;
using jwl.infra;
using jwl.jira.api.rest.request;
using jwl.jira.Exceptions;
using jwl.jira.Flavours;
using jwl.wadl;

Expand Down Expand Up @@ -216,7 +217,16 @@ public async Task AddWorkLog(string issueKey, DateOnly day, int timeSpentSeconds
Content = new FormUrlEncodedContent(args),
};
httpRequest.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(WadlRepresentation.MediaTypeJson));
HttpResponseMessage response = await _httpClient.SendAsync(httpRequest);

HttpResponseMessage response;
try
{
response = await _httpClient.SendAsync(httpRequest);
}
catch (Exception ex)
{
throw new AddWorkLogException(issueKey, day.ToDateTime(TimeOnly.MinValue), timeSpentSeconds, ex);
}

if (response.Content.Headers.ContentType?.MediaType != WadlRepresentation.MediaTypeJson)
throw new InvalidDataException($"Invalid media type returned ({response.Content.Headers.ContentType?.MediaType ?? string.Empty})");
Expand Down Expand Up @@ -257,6 +267,7 @@ private async Task<WadlApplication> GetWADL()
{
Uri uri = new Uri($"{_flavourOptions.PluginBaseUri}/application.wadl", UriKind.Relative);
using Stream response = await _httpClient.GetStreamAsync(uri);

if (response == null)
throw new HttpRequestException($"Empty content received from ${uri}");

Expand Down
66 changes: 61 additions & 5 deletions jwl.jira/Flavours/VanillaJiraClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ namespace jwl.jira;
using System.Xml;
using jwl.infra;
using jwl.jira.api.rest.response;
using jwl.jira.Exceptions;
using jwl.jira.Flavours;

public class VanillaJiraClient
Expand Down Expand Up @@ -89,7 +90,17 @@ public async Task<WorkLog[]> GetIssueWorkLogs(DateOnly from, DateOnly to, string
.Add(@"worklog")
};

var response = await _httpClient.GetAsJsonAsync<api.rest.response.JiraIssueWorklogs>(uriBuilder.Uri.PathAndQuery);
string uri = uriBuilder.Uri.PathAndQuery.TrimStart('/');

JiraIssueWorklogs? response;
try
{
response = await _httpClient.GetAsJsonAsync<JiraIssueWorklogs>(uri);
}
catch (Exception ex)
{
throw new GetIssueWorkLogsException(issueKey, from.ToDateTime(TimeOnly.MinValue), to.ToDateTime(TimeOnly.MinValue).AddDays(1), ex);
}

(DateTime minDt, DateTime supDt) = DateOnlyUtils.DateOnlyRangeToDateTimeRange(from, to);

Expand Down Expand Up @@ -141,8 +152,10 @@ public async Task AddWorkLog(string issueKey, DateOnly day, int timeSpentSeconds
};

StringBuilder commentBuilder = new StringBuilder();

if (activity != null)
commentBuilder.Append($"({activity}){Environment.NewLine}");

commentBuilder.Append(comment);

var request = new api.rest.request.JiraAddWorklogByIssueKey(
Expand All @@ -155,7 +168,20 @@ public async Task AddWorkLog(string issueKey, DateOnly day, int timeSpentSeconds
Comment: commentBuilder.ToString()
);

HttpResponseMessage response = await _httpClient.PostAsJsonAsync(uriBuilder.Uri.PathAndQuery, request);
HttpResponseMessage response;
try
{
response = await _httpClient.PostAsJsonAsync(uriBuilder.Uri.PathAndQuery.TrimStart('/'), request);
}
catch (Exception ex)
{
throw new AddWorkLogException(issueKey, day.ToDateTime(TimeOnly.MinValue), timeSpentSeconds, ex)
{
Activity = activity,
Comment = comment
};
}

await CheckHttpResponseForErrorMessages(response);
}

Expand Down Expand Up @@ -190,7 +216,16 @@ public async Task DeleteWorkLog(long issueId, long worklogId, bool notifyUsers =
.Add(@"notifyUsers", notifyUsers.ToString().ToLower())
};

HttpResponseMessage response = await _httpClient.DeleteAsync(uriBuilder.Uri.PathAndQuery);
HttpResponseMessage response;
try
{
response = await _httpClient.DeleteAsync(uriBuilder.Uri.PathAndQuery.TrimStart('/'));
}
catch (Exception ex)
{
throw new DeleteWorklogException(issueId, worklogId, ex);
}

await CheckHttpResponseForErrorMessages(response);
}

Expand All @@ -213,7 +248,20 @@ public async Task UpdateWorkLog(string issueKey, long worklogId, DateOnly day, i
Comment: comment
);

HttpResponseMessage response = await _httpClient.PutAsJsonAsync(uriBuilder.Uri.PathAndQuery, request);
HttpResponseMessage response;
try
{
response = await _httpClient.PutAsJsonAsync(uriBuilder.Uri.PathAndQuery.TrimStart('/'), request);
}
catch (Exception ex)
{
throw new UpdateWorklogException(issueKey, worklogId, day.ToDateTime(TimeOnly.MinValue), timeSpentSeconds, ex)
{
Activity = activity,
Comment = comment
};
}

await CheckHttpResponseForErrorMessages(response);
}

Expand All @@ -225,6 +273,14 @@ public async Task UpdateWorkLog(string issueKey, long worklogId, DateOnly day, i
Query = new UriQueryBuilder()
.Add(@"username", UserName)
};
return await _httpClient.GetAsJsonAsync<api.rest.common.JiraUserInfo>(uriBuilder.Uri.PathAndQuery);

try
{
return await _httpClient.GetAsJsonAsync<api.rest.common.JiraUserInfo>(uriBuilder.Uri.PathAndQuery.TrimStart('/'));
}
catch (Exception ex)
{
throw new JiraClientException($"Error retrieving user {UserName} info", ex);
}
}
}

0 comments on commit 26506f7

Please sign in to comment.