mangopay2-net-sdk icon indicating copy to clipboard operation
mangopay2-net-sdk copied to clipboard

ArgumentNullException on MangoPayFailure

Open outofrange-consulting opened this issue 1 year ago • 0 comments

On some occasion during MangoPay failures, we receive what we suppose is a HTTP 500 error (not sure because the mapping of the error code happens after the ArgumentNullException). In your SDK, you try to deserialize the content of the response as a ErrorResponse, but it fails because the content is null.

I won't make a PR because their is no guideline, but here is the modified code :

using System;

namespace MangoPay.SDK.Core
{
    /// <summary>Response exception class.</summary>
    public class ResponseException : ApplicationException
    {
        /// <summary>Instantiates new ResponseException object.</summary>
        public ResponseException()
        {
        }

        /// <summary>Instantiates new ResponseException object.</summary>
        /// <param name="message">JSON data that came as a response from API.</param>
        /// <param name="responseStatusCode">Response status code from API.</param>
        public ResponseException(string message, int responseStatusCode) : base(message)
        {
            this.ResponseErrorRaw = message;
            this.ResponseStatusCode = responseStatusCode;
            this.ResponseError = ResponseError.FromJSON(message);
        }

        /// <summary>Raw text data that came as response from API.</summary>
        public string ResponseErrorRaw;

        /// <summary>Deserialized response error data.</summary>
        public ResponseError ResponseError = new ResponseError();

        /// <summary>Response status code from API.</summary>
        public int ResponseStatusCode;
    }
}
using Newtonsoft.Json;
using System.Collections.Generic;

namespace MangoPay.SDK.Core
{
    /// <summary>Response error class, used as part of ResponseException object. 
    /// You don't need to instantiate it by yourself - SDK will take care of this for you.</summary>
    public sealed class ResponseError
    {
        internal ResponseError () { }

        /// <summary>General error text message.</summary>
        public string Message;

        /// <summary>Type of error.</summary>
        public string Type;
        
        /// <summary>Error identifier.</summary>
        public string Id;

        /// <summary>Date (UNIX timestamp).</summary>
        public long Date;

        /// <summary>Collection of field name / error description pairs.</summary>
        public Dictionary<string, string> errors;

        /// <summary>Deserializes JSON ResponseError instance.</summary>
        /// <param name="serializedResponseError">JSON-serialized ResponseError instance.</param>
        /// <returns>Returns new instance of ResponseError class or null if deserialization failed.</returns>
        public static ResponseError FromJSON(string serializedResponseError)
        {
            if (string.IsNullOrEmpty(serializedResponseError))
            {
                return null;
            }

            try
            {
                return JsonConvert.DeserializeObject<ResponseError>(serializedResponseError);
            }
            catch (JsonException)
            {
                return null;
            }
        }
    }
}

The important part is to check for null (and maybe empty) string before trying to deserialize the ErrorResponse.

outofrange-consulting avatar Oct 13 '23 12:10 outofrange-consulting