/// <summary> /// Gets the error message from the response body if it exists. /// </summary> /// <param name="response">The response from the server.</param> /// <returns>The error messsage, or null if no error message was found.</returns> protected static async Task <string> GetServerErrorMessage(RiotResponse response) { // Try to get the error message from the server if it exists. if (response?.Response?.Content == null) { return(null); } try { JToken token; using (var stream = await response.Response.Content.ReadAsStreamAsync().ConfigureAwait(false)) using (var reader = new StreamReader(stream)) using (var jsonReader = new JsonTextReader(reader)) { token = JToken.ReadFrom(jsonReader); } if (token["status"] is JObject) { token = token["status"]; } var message = token.Value <string>("message"); return(message); } catch { return(null); } }
/// <summary> /// Creates a new <see cref="RestTimeoutException"/> instance. /// </summary> /// <param name="response">The response.</param> /// <param name="innerException">The exception that is the cause of the current exception.</param> public RestTimeoutException(RiotResponse response, Exception innerException) : base(response, "A REST request timed out.", innerException) { }
/// <summary> /// Creates a new <see cref="RateLimitExceededException"/> instance. /// </summary> /// <param name="response">The response.</param> /// <param name="message">A message that describes the error.</param> /// <param name="innerException">The exception that is the cause of the current exception.</param> public RateLimitExceededException(RiotResponse response, string message, Exception innerException) : base(response, message, innerException) { }
/// <summary> /// Creates a new <see cref="RateLimitExceededException"/> instance. /// </summary> /// <param name="response">The response.</param> /// <param name="innerException">The exception that is the cause of the current exception.</param> public RateLimitExceededException(RiotResponse response, Exception innerException) : base(response, "The rate limit for the current API key was exceeded.", innerException) { }
/// <summary> /// Creates a new <see cref="NotFoundException"/> instance. /// </summary> /// <param name="response">The response.</param> /// <param name="message">A message that describes the error.</param> /// <param name="innerException">The exception that is the cause of the current exception.</param> public NotFoundException(RiotResponse response, string message, Exception innerException) : base(response, message, innerException) { }
/// <summary> /// Creates a new <see cref="RestException"/> instance. /// </summary> /// <param name="response">The response.</param> /// <param name="innerException">The exception that is the cause of the current exception.</param> public RestException(RiotResponse response, Exception innerException) : this(response, "A REST request failed." + (response?.Response?.StatusCode != null ? " Status code: " + (int)response.Response.StatusCode : string.Empty), innerException) { }
/// <summary> /// Creates a new <see cref="ConnectionFailedException"/> instance. /// </summary> /// <param name="response">The response.</param> /// <param name="message">A message that describes the error.</param> /// <param name="innerException">The exception that is the cause of the current exception.</param> public ConnectionFailedException(RiotResponse response, string message, Exception innerException) : base(response, message, innerException) { }
/// <summary> /// Creates a new <see cref="RestTimeoutException"/> instance. /// </summary> /// <param name="response">The response.</param> /// <param name="message">A message that describes the error.</param> /// <param name="innerException">The exception that is the cause of the current exception.</param> public RestTimeoutException(RiotResponse response, string message, Exception innerException) : base(response, message, innerException) { }
protected RestException(SerializationInfo info, StreamingContext context) : base(info, context) { response = (RiotResponse)info.GetValue("Response", typeof(RiotResponse)); }
/// <summary> /// Creates a new <see cref="RestException"/> instance. /// </summary> /// <param name="response">The response.</param> /// <param name="message">A message that describes the error.</param> /// <param name="innerException">The exception that is the cause of the current exception.</param> public RestException(RiotResponse response, string message, Exception innerException) : base(message, innerException) { this.response = response; }
/// <summary> /// Creates a new <see cref="RestException"/> instance. /// </summary> /// <param name="response">The response.</param> /// <param name="innerException">The exception that is the cause of the current exception.</param> public RestException(RiotResponse response, Exception innerException) : this(response, "A REST request failed." + (response != null ? " Status code: " + (int)response.Response.StatusCode : string.Empty), innerException) { }
/// <summary> /// Creates a new <see cref="RestException"/> instance. /// </summary> /// <param name="response">The response.</param> /// <param name="message">A message that describes the error.</param> public RestException(RiotResponse response, string message) : this(response, message, null) { }
/// <summary> /// Creates a new <see cref="ResponseEventArgs"/> instance. /// </summary> /// <param name="response">The response for the request that caused the event.</param> /// <param name="errorMessage">The error message contained in te response, if any.</param> public ResponseEventArgs(RiotResponse response, string errorMessage = null) { this.response = response; this.errorMessage = errorMessage; }
/// <summary> /// Creates a new <see cref="ConnectionFailedException"/> instance. /// </summary> /// <param name="response">The response.</param> public ConnectionFailedException(RiotResponse response) : this(response, (Exception)null) { }
/// <summary> /// Creates a new <see cref="ConnectionFailedException"/> instance. /// </summary> /// <param name="response">The response.</param> /// <param name="innerException">The exception that is the cause of the current exception.</param> public ConnectionFailedException(RiotResponse response, Exception innerException) : base(response, "Failed to connect to the server.", innerException) { }
/// <summary> /// Creates a new <see cref="ConnectionFailedException"/> instance. /// </summary> /// <param name="response">The response.</param> /// <param name="message">A message that describes the error.</param> public ConnectionFailedException(RiotResponse response, string message) : base(response, message) { }
/// <summary> /// Creates a new <see cref="NotFoundException"/> instance. /// </summary> /// <param name="response">The response.</param> /// <param name="message">A message that describes the error.</param> public NotFoundException(RiotResponse response, string message) : base(response, message) { }
/// <summary> /// Creates a new <see cref="RateLimitExceededException"/> instance. /// </summary> /// <param name="response">The response.</param> public RateLimitExceededException(RiotResponse response) : this(response, (Exception)null) { }
/// <summary> /// Creates a new <see cref="RateLimitExceededException"/> instance. /// </summary> /// <param name="response">The response.</param> /// <param name="message">A message that describes the error.</param> public RateLimitExceededException(RiotResponse response, string message) : base(response, message) { }
/// <summary> /// Creates a new <see cref="RestTimeoutException"/> instance. /// </summary> /// <param name="response">The response.</param> public RestTimeoutException(RiotResponse response) : this(response, (Exception)null) { }
/// <summary> /// Creates a new <see cref="RestTimeoutException"/> instance. /// </summary> /// <param name="response">The response.</param> /// <param name="message">A message that describes the error.</param> public RestTimeoutException(RiotResponse response, string message) : base(response, message) { }
/// <summary> /// Creates a new <see cref="NotFoundException"/> instance. /// </summary> /// <param name="response">The response.</param> public NotFoundException(RiotResponse response) : this(response, (Exception)null) { }
/// <summary> /// Creates a new <see cref="NotFoundException"/> instance. /// </summary> /// <param name="response">The response.</param> /// <param name="innerException">The exception that is the cause of the current exception.</param> public NotFoundException(RiotResponse response, Exception innerException) : base(response, "The requested resource was not found.", innerException) { }
/// <summary> /// Determines which action to take for the given response. /// </summary> /// <param name="response">An <see cref="HttpResponseMessage"/>.</param> /// <param name="attemptCount">The number of times the request has been attempted so far.</param> /// <param name="token">The cancellation token to cancel the operation.</param> /// <returns>A <see cref="ResponseAction"/>.</returns> protected virtual async Task <ResponseAction> DetermineResponseAction(RiotResponse response, int attemptCount, CancellationToken token) { if (response.TimedOut) { var args = new RetryEventArgs(response, attemptCount) { Retry = Settings.RetryOnTimeout }; OnRequestTimedOut(args); // Note: never retry if the token is cancelled. It will certainly fail the next time, too. if (args.Retry && !token.IsCancellationRequested) { return(ResponseAction.Retry); } if (Settings.ThrowOnError) { throw new RestTimeoutException(response, response.Exception); } return(ResponseAction.ReturnDefault); } if (response.Response == null) { var args = new RetryEventArgs(response, attemptCount) { Retry = Settings.RetryOnConnectionFailure }; OnConnectionFailed(args); if (args.Retry) { return(ResponseAction.Retry); } if (Settings.ThrowOnError) { throw new ConnectionFailedException(response, response.Exception); } return(ResponseAction.ReturnDefault); } var statusCode = (int)response.Response.StatusCode; if (statusCode == 429) { var args = new RetryEventArgs(response, attemptCount) { Retry = Settings.RetryOnRateLimitExceeded }; OnRateLimitExceeded(args); if (args.Retry) { return(ResponseAction.Retry); } if (Settings.ThrowOnError) { throw new RateLimitExceededException(response); } return(ResponseAction.ReturnDefault); } if (statusCode == 404) { OnResourceNotFound(new ResponseEventArgs(response)); if (Settings.ThrowOnNotFound) { throw new NotFoundException(response); } return(ResponseAction.ReturnDefault); } if (statusCode >= 500) { var args = new RetryEventArgs(response, attemptCount) { Retry = Settings.RetryOnServerError }; OnServerError(args); if (args.Retry) { return(ResponseAction.Retry); } if (Settings.ThrowOnError) { var message = await GetServerErrorMessage(response).ConfigureAwait(false); if (message != null) { throw new RestException(response, message); } else { throw new RestException(response); } } return(ResponseAction.ReturnDefault); } if (statusCode >= 400) { var message = await GetServerErrorMessage(response).ConfigureAwait(false); OnResponseError(new ResponseEventArgs(response, message)); if (Settings.ThrowOnError) { if (message != null) { throw new RestException(response, message, response.Exception); } else { throw new RestException(response, response.Exception); } } return(ResponseAction.ReturnDefault); } return(ResponseAction.Return); }
/// <summary> /// Creates a new <see cref="ResponseEventArgs"/> instance. /// </summary> /// <param name="response">The response for the request that caused the event.</param> public ResponseEventArgs(RiotResponse response) { this.response = response; }