Skip to content

Utils.StrictMode is not null safe when RECURLY_STRICT_MODE env var is not set #674

@ghost

Description

Describe the bug

We have an issue where one of our CreateSubscriptionAsync calls is failing. Instead of giving us a real error, we are instead getting a Null Reference Exception. Looking at the SDK code, it would appear that our call is trigger an error that has an unknown type. Because of that unknown type, we are hitting the default switch action here: https://github.com/recurly/recurly-client-dotnet/blob/v3-v2021-02-25/Recurly/Errors/Factory.cs#L192

It would appear that the Utils.StrictMode is trying to look at an environment variable (which we do not have set) here:

strictMode = Environment.GetEnvironmentVariable("RECURLY_STRICT_MODE").ToUpper() == "TRUE";

Environment.GetEnvironmentVariable(...) returns null when a variable is not found, so its throwing the null reference error on the following .ToUpper() call

EDIT: After setting RECURLY_STRICT_MODE to FALSE, the underlaying error message we get is: An Undefined error occurred. The address provided is invalid, could not determine taxing jurisdictions

Stack trace:

System.NullReferenceException: Object reference not set to an instance of an object.
at Recurly.Utils.get_StrictMode()
at Recurly.Errors.Factory.Create(ErrorMayHaveTransaction err)
at Recurly.BaseClient.HandleResponse(IRestResponse resp)
at Recurly.BaseClient.<>c__DisplayClass18_0`1.<MakeRequestAsync>b__0(Task`1 t)
at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()
at System.Threading.Tasks.Task.<>c.<.cctor>b__274_0(Object obj)
at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location where exception was thrown ---
at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
--- End of stack trace from previous location where exception was thrown ---
at Recurly.BaseClient.MakeRequestAsync[T](Method method, String url, Request body, Dictionary`2 queryParams, RequestOptions options, CancellationToken cancellationToken)

To Reproduce

Have the Error Factory create an error that has an unknown error type associated with it

Expected behavior

A generic error is thrown, rather than a null reference exception.

Your Environment

C# Nuget package Recurly 4.9.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions