/* SPDX-License-Identifier: Apache-2.0 * * The OpenSearch Contributors require contributions made to * this file be licensed under the Apache-2.0 license or a * compatible open source license. */ /* * Modifications Copyright OpenSearch Contributors. See * GitHub history for details. * * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright * ownership. Elasticsearch B.V. licenses this file to you under * the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ using System; using System.Runtime.Serialization; using System.Text; using OpenSearch.Net; namespace OpenSearch.Client { /// /// A response from OpenSearch /// public interface IResponse : IOpenSearchResponse { /// /// A lazily computed, human readable string representation of what happened during a request for both successful and /// failed requests. Useful whilst developing or to log when is false on responses. /// [IgnoreDataMember] string DebugInformation { get; } /// /// Checks if a response is functionally valid or not. /// This is a OpenSearch.Client abstraction to have a single property to check whether there was something wrong with a request. /// /// For instance, an OpenSearch bulk response always returns 200 and individual bulk items may fail, /// will be false in that case. /// /// /// You can also configure the client to always throw an using /// if the response is not valid /// /// [IgnoreDataMember] bool IsValid { get; } /// /// If the request resulted in an exception on the client side this will hold the exception that was thrown. /// /// This property is a shortcut to 's /// and /// is possibly set when is false depending on the cause of the error /// /// /// You can also configure the client to always throw an using /// if the response is not valid /// /// [IgnoreDataMember] Exception OriginalException { get; } /// /// If the response results in an error on OpenSearch's side an
error
element will be returned, this is /// mapped to /// in OpenSearch.Client. /// Possibly set when is false, depending on the cause of the error /// /// You can also configure the client to always throw an using /// if the response is not valid /// ///
[IgnoreDataMember] ServerError ServerError { get; } } public abstract class ResponseBase : IResponse { private Error _error; private IApiCallDetails _originalApiCall; private ServerError _serverError; private int? _statusCode; /// Returns useful information about the request(s) that were part of this API call. public virtual IApiCallDetails ApiCall => _originalApiCall; /// public string DebugInformation { get { var sb = new StringBuilder(); sb.Append($"{(!IsValid ? "Inv" : "V")}alid OpenSearch.Client response built from a "); sb.AppendLine(ApiCall?.ToString().ToCamelCase() ?? "null ApiCall which is highly exceptional, please open a bug if you see this"); if (!IsValid) DebugIsValid(sb); if (ApiCall != null) ResponseStatics.DebugInformationBuilder(ApiCall, sb); return sb.ToString(); } } /// public virtual bool IsValid { get { var statusCode = ApiCall?.HttpStatusCode; if (statusCode == 404) return false; return (ApiCall?.Success ?? false) && ServerError == null; }} /// public Exception OriginalException => ApiCall?.OriginalException; /// public ServerError ServerError { get { if (_serverError != null) return _serverError; if (_error == null) return null; _serverError = new ServerError(_error, _statusCode); return _serverError; } } [DataMember(Name = "error")] internal Error Error { get => _error; set { _error = value; _serverError = null; } } [DataMember(Name = "status")] internal int? StatusCode { get => _statusCode; set { _statusCode = value; _serverError = null; } } [IgnoreDataMember] IApiCallDetails IOpenSearchResponse.ApiCall { get => _originalApiCall; set => _originalApiCall = value; } bool IOpenSearchResponse.TryGetServerErrorReason(out string reason) { reason = ServerError?.Error?.ToString(); return !reason.IsNullOrEmpty(); } /// Subclasses can override this to provide more information on why a call is not valid. protected virtual void DebugIsValid(StringBuilder sb) { } public override string ToString() => $"{(!IsValid ? "Inv" : "V")}alid OpenSearch.Client response built from a {ApiCall?.ToString().ToCamelCase()}"; } }