Example #1
0
        private async Task <TResponse> PerformHttp <TRequest, TResponse>(string path, HttpMethod method, TRequest requestBody, CancellationToken token) where TResponse : class
        {
            HttpClient httpClient = _httpClientProducer.CreateClient();

            using HttpRequestMessage req = new HttpRequestMessage(method, path);

            if (requestBody != null)
            {
                req.Content = new JsonContent <TRequest>(_serializer, requestBody);
            }

            // Login if needed, then sign the request
            await _requestSigner.LoginIfNeeded(this, token);

            await _requestSigner.Sign(httpClient, req, token);

            // Issue the request
            using HttpResponseMessage resp = await httpClient.SendAsync(req, HttpCompletionOption.ResponseContentRead, token);

            if (resp.Content.Headers.ContentType.MediaType != "application/json")
            {
                throw new Exception($"API request did not result in a Json object. Path: '{path}'.");
            }

            if (_logger.IsEnabled(LogLevel.Trace))
            {
                // Log request / Response
                // Note: It should be fine to read the content twice, as HttpCompletionOption.ResponseContentRead is set
                string responseBody = await resp.Content.ReadAsStringAsync();

                _logger.LogTrace("Received {Code} for {Path}, with body: {Body}", resp.StatusCode, req.RequestUri, responseBody);
            }

            JObject obj = Parse <JObject>(await resp.Content.ReadAsStreamAsync());

            if (obj.ContainsKey("errorMessage") /* && obj.ContainsKey("errorType")*/)
            {
                // This is an error, regardless of what the status code is
                throw new Exception($"API responded with an error: {obj.Value<string>("errorMessage")}. Path: '{path}'.");
            }

            if (resp.StatusCode == HttpStatusCode.OK)
            {
                return(obj.ToObject <TResponse>());
            }

            // Something is wrong, try fetching a message
            if (obj.TryGetValue("errorMessage", out JToken errorMsg) || obj.TryGetValue("message", out errorMsg))
            {
                throw new Exception($"API resulted in a non-success status code. Message: {errorMsg}. Path: '{path}'.");
            }

            throw new Exception($"API resulted in a non-success status code. No futher details available. Path: '{path}'.");
        }
        /// <inheritdoc />
        protected override async Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            await _requestSigner.Sign(request).ConfigureAwait(false);

            return(await base.SendAsync(request, cancellationToken).ConfigureAwait(false));
        }