NGitLab icon indicating copy to clipboard operation
NGitLab copied to clipboard

Handle the 404 empty response when getting a single artifact file

Open PMExtra opened this issue 2 years ago • 3 comments

https://docs.gitlab.com/ee/api/job_artifacts.html#download-a-single-artifact-file-by-job-id https://docs.gitlab.com/ee/api/job_artifacts.html#download-a-single-artifact-file-from-specific-tag-or-branch

When downloading a single artifact file that does not exist, GitLab will return an empty 404 response with a zero-length body.

Maybe this behavior only appeared in 16.0+, I upgraded from 15.6 to 16.3 yesterday and then met this problem I've never seen before.

Anyway, we can reproduce it from gitlab.com, eg.

  • 200: https://gitlab.com/api/v4/projects/gitlab-org%2Fgitlab/jobs/5527580160/artifacts/coverage-frontend/lcov.info
  • 404: https://gitlab.com/api/v4/projects/gitlab-org%2Fgitlab/jobs/5527580160/artifacts/foo/bar

For the 404 empty response, NGitLab will throw a System.IO.IOException from GitLabRequest.HandleWebException at https://github.com/ubisoft/NGitLab/blob/6.42.2/NGitLab/Impl/HttpRequestor.GitLabRequest.cs#L133

Stacktrace:

System.IO.IOException: The response ended prematurely, with at least 2 additional bytes expected.
   at System.Net.Http.HttpConnection.ContentLengthReadStream.Read(Span`1 buffer)
   at System.IO.StreamReader.ReadBuffer()
   at System.IO.StreamReader.ReadToEnd()
   at NGitLab.Impl.HttpRequestor.GitLabRequest.HandleWebException(WebException ex) in /_/NGitLab/Impl/HttpRequestor.GitLabRequest.cs:line 133
   at NGitLab.Impl.HttpRequestor.GitLabRequest.GetResponseImpl(RequestOptions options) in /_/NGitLab/Impl/HttpRequestor.GitLabRequest.cs:line 106
   at NGitLab.Extensions.FunctionRetryExtensions.Retry[T](Func`1 action, Func`3 predicate, TimeSpan waitTime, Int32 maxRetryCount, Boolean useExponentialBackoff) in /_/NGitLab/Extensions/FunctionRetryExtensions.cs:line 41
   at NGitLab.Impl.HttpRequestor.Stream(String tailAPIUrl, Action`1 parser) in /_/NGitLab/Impl/HttpRequestor.cs:line 118
   at NGitLab.Impl.JobClient.GetJobArtifact(Int32 jobId, String path)

PMExtra avatar Nov 14 '23 03:11 PMExtra

~By the way, shall we always disable the retry policy for this case?~ (It will only retry when getting responses with code >= 500 or timeout)

PMExtra avatar Nov 14 '23 03:11 PMExtra

Sorry, it's a GitLab bug: https://gitlab.com/gitlab-org/gitlab/-/issues/414807

But it seems like it won't be fixed recently. Can we make some improvements for NGitLab to avoid it?

PMExtra avatar Nov 14 '23 03:11 PMExtra

You can submit a PR to improve this behavior. Maybe a try/catch in https://github.com/ubisoft/NGitLab/blob/6.42.2/NGitLab/Impl/HttpRequestor.GitLabRequest.cs#L127 is enough.

meziantou avatar Nov 14 '23 14:11 meziantou