Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Guard code in api stub methods #348

Merged
merged 4 commits into from
Nov 9, 2020
Merged

Conversation

nr-ahemsath
Copy link
Member

Description

A customer reported exceptions being thrown from one of our API methods when called without the agent attached (meaning that the stub methods in NewRelic.cs were being executed, rather than the "real" API methods that the stubs get rewritten to when the agent is attached). This PR attempts to guard against any potential exceptions in two ways:

Add try/catch blocks around System.Diagnostics.Trace.WriteLine calls to prevent any exceptions thrown from use of this method from affecting a customer app.

Put nameof() around parameters passed to string.format to prevent any issues that might arise from trying to .ToString() objects passed in by users.

Testing

Unit tests pass. Did a quick smoke test of an app which used the API without the agent attached and it behaved as expected.

Changelog

Changelog updated

Add try/catch blocks around System.Diagnostics.Trace.WriteLine calls to prevent any exceptions thrown from use of this method from affecting a customer app.

Put nameof() around parameters passed to string.format to prevent any issues that might arise from trying to .ToString() objects passed in by customers.
@nr-ahemsath nr-ahemsath added the bug Something isn't working label Nov 6, 2020
System.Diagnostics.Trace.WriteLine("NewRelic.SetUserParameters(String userName, String accountName, String productName)");
try
{
System.Diagnostics.Trace.WriteLine("NewRelic.SetUserParameters(String userName, String accountName, String productName)");
Copy link
Contributor

@lspangler584 lspangler584 Nov 7, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So if params are nullable, the compiler doesn't require they be referenced? If that's the case, it looks like SetApplicationName needs a reference to at least the first param.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should do nameof(paramName) on all params of all methods regardless of whether they are nullable.

Comment on lines 748 to 755
try
{
System.Diagnostics.Trace.WriteLine(string.Format("NewRelic.RecordCustomEvent({0},{1})", nameof(eventType), nameof(attributes)));
}
catch
{
// Swallow any exception thrown from here
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
try
{
System.Diagnostics.Trace.WriteLine(string.Format("NewRelic.RecordCustomEvent({0},{1})", nameof(eventType), nameof(attributes)));
}
catch
{
// Swallow any exception thrown from here
}
System.Diagnostics.Trace.WriteLine(string.Format("NewRelic.RecordCustomEvent({0},{1})", nameof(eventType), nameof(attributes)));

Copy link
Member

@alanwest alanwest Nov 7, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All the methods should be safe without the try/catch now that we're not attempting to ToString the parameters.

For example, this RecordCustomEvent method can be problematic if the underlying type's ToString method is not thread-safe when attributes.ToString() is called. The type would be something like:

class MyEnumerable : IEnumerable<KeyValuePair<string, object>>
{
    // Performs work that is not thread-safe
    public override string ToString() ...
}

Dictionary<string, object> is such a type. https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2. However, it's ToString method is likely safe, so it would likely have to be some custom type.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we positively established that the reason the customer (or any customer in general) might experience an exception from these tracing calls can only be a non-threadsafe .ToString(). I'd prefer the belt-and-suspenders approach for maximum safety.

@lspangler584
Copy link
Contributor

After discussion, decided to leave in try/catch since we are not certain the customer exception issue is resolved, and try/catch would guard against any future issues.

@lspangler584 lspangler584 merged commit a2d3b08 into main Nov 9, 2020
@lspangler584 lspangler584 deleted the api-stub-method-hardening branch November 9, 2020 19:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants