void CanConstructRequestException() { RequestException requestException; foreach (var type in new MessageType[] { MessageType.Debug, MessageType.Error, MessageType.Fatal, MessageType.Information, MessageType.Warning }) { var details = new ReadOnlyCollection<Message>(new Message[] { new Message(type, "Information on the cause of the RequestException") }); requestException = new RequestException(new HttpResponseMessage(HttpStatusCode.InternalServerError), details); Assert.Equal(string.Format("500: Internal Server Error\n {0}: Information on the cause of the RequestException", type), requestException.Message); Assert.Equal(HttpStatusCode.InternalServerError, requestException.StatusCode); Assert.Equal(1, requestException.Details.Count); Assert.Equal(details, requestException.Details.AsEnumerable()); } requestException = new RequestException(new HttpResponseMessage(HttpStatusCode.NoContent), null); Assert.Equal("204: No Content", requestException.Message); Assert.Equal(0, requestException.Details.Count); Assert.Equal(HttpStatusCode.NoContent, requestException.StatusCode); for (int i = 2; i < 10; ++i) { var message = new StringBuilder("204: No Content"); var details = new Message[i]; for (int j = 0; j < i; ++j) { details[j] = new Message(MessageType.Warning, "Information on the cause of the RequestException"); message.Append("\n "); message.Append(details[j]); } requestException = new RequestException( new HttpResponseMessage(HttpStatusCode.NoContent), new ReadOnlyCollection<Message>(details)); Assert.Equal(HttpStatusCode.NoContent, requestException.StatusCode); Assert.Equal(message.ToString(), requestException.Message); Assert.Equal(i, requestException.Details.Count); Assert.Equal(details, requestException.Details.AsEnumerable()); } }
/// <summary> /// Throw request exception asynchronous. /// </summary> /// <exception cref="RequestException"> /// Thrown when a Request error condition occurs. /// </exception> /// <returns> /// A <see cref="Task"/> representing the operation. /// </returns> internal async Task ThrowRequestExceptionAsync() { var details = await Splunk.Client.Message.ReadMessagesAsync(this.XmlReader).ConfigureAwait(false); RequestException requestException; switch (this.Message.StatusCode) { case HttpStatusCode.BadRequest: requestException = new BadRequestException(this.Message, details); break; case HttpStatusCode.Forbidden: requestException = new UnauthorizedAccessException(this.Message, details); break; case HttpStatusCode.InternalServerError: requestException = new InternalServerErrorException(this.Message, details); break; case HttpStatusCode.NotFound: requestException = new ResourceNotFoundException(this.Message, details); break; case HttpStatusCode.Unauthorized: requestException = new AuthenticationFailureException(this.Message, details); break; default: requestException = new RequestException(this.Message, details); break; } throw requestException; }
/// <summary> /// Throws a <see cref="RequestException"/> if the current <see cref= /// "Response.Message.StatusCode"/> is different than <see cref= /// "expected"/>. /// </summary> /// <param name="expected"> /// The expected <see cref="HttpStatusCode"/>. /// </param> /// <returns></returns> public async Task EnsureStatusCodeAsync(HttpStatusCode expected) { var statusCode = this.Message.StatusCode; if (statusCode == expected) return; var details = await Splunk.Client.Message.ReadMessagesAsync(this.XmlReader); RequestException requestException; switch (statusCode) { case HttpStatusCode.Forbidden: requestException = new UnauthorizedAccessException(this.Message, details); break; case HttpStatusCode.NotFound: requestException = new ResourceNotFoundException(this.Message, details); break; case HttpStatusCode.Unauthorized: requestException = new AuthenticationFailureException(this.Message, details); break; default: requestException = new RequestException(this.Message, details); break; } throw requestException; }
/// <summary> /// Refreshes the cached state of the current <see cref="Entity<TEntity>"/>. /// </summary> public override async Task GetAsync() { //// TODO: This retry logic is for jobs. Parmeterize it and move it into the Job class // FJR: I assume the retry logic is for jobs, since nothing else requires this. I suggest moving it // into Job. Also, it's insufficient. If you're just trying to get some state, this will do it, but // as of Splunk 6, getting a 200 and content back does not imply you have all the fields. For pivot // support, they're now shoving fields in as they become ready, so you have to wait until the dispatchState // field of the Atom entry reaches a certain point. RequestException requestException = null; for (int i = 3; i > 0; --i) { try { //// Guarantee: unique result because entities have specific namespaces using (var response = await this.Context.GetAsync(this.Namespace, this.ResourceName)) { //// TODO: Use Response.EnsureStatusCode. Is it true that gets always return HttpStatusCode.OK? if (response.Message.StatusCode == HttpStatusCode.NoContent) { throw new RequestException(response.Message, new Message(MessageType.Warning, string.Format("Resource '{0}/{1}' is not ready.", this.Namespace, this.ResourceName))); } if (!response.Message.IsSuccessStatusCode) { throw new RequestException(response.Message, await Message.ReadMessagesAsync(response.XmlReader)); } var reader = response.XmlReader; await reader.ReadAsync(); if (reader.NodeType == XmlNodeType.XmlDeclaration) { await response.XmlReader.ReadAsync(); } if (reader.NodeType != XmlNodeType.Element) { throw new InvalidDataException(); // TODO: Diagnostics } AtomEntry entry; if (reader.Name == "feed") { AtomFeed feed = new AtomFeed(); await feed.ReadXmlAsync(reader); int count = feed.Entries.Count; foreach (var feedEntry in feed.Entries) { string id = feedEntry.Title; id.Trim(); } if (feed.Entries.Count != 1) { throw new InvalidDataException(); // TODO: Diagnostics } entry = feed.Entries[0]; } else { entry = new AtomEntry(); await entry.ReadXmlAsync(reader); } this.Snapshot = new EntitySnapshot(entry); } return; } catch (RequestException e) { if (e.StatusCode != System.Net.HttpStatusCode.NoContent) { throw; } requestException = e; } await Task.Delay(500); } throw requestException; }