Skip to content

OptionsDescription should survive a property getter that throws, and skip indexers / set-only properties #590

Closed

Description

@jeremydmiller

OptionsDescription(object subject) is a diagnostic view built by calling arbitrary property getters on somebody else's configuration object. Today a single getter that throws takes the whole description with it, and anything built on top of the description goes with it.

Real-world report (JasperFx/wolverine#3740): AzureServiceBusTransport.HostName threw a NullReferenceException for credential-based connections, so a Wolverine service could never build its ServiceCapabilities snapshot, so CritterWatch never completed a handshake for that service — permanently, since the same doomed read is retried on every batch.

System.Reflection.TargetInvocationException:
   at JasperFx.Descriptors.OptionsValue.Read (OptionsValue.cs:53)
   at JasperFx.Descriptors.OptionsDescription.readProperties (OptionsDescription.cs:156)
   ...
Inner exception System.NullReferenceException:
   at Wolverine.AzureServiceBus.AzureServiceBusTransport.get_HostName

Two related holes in the same walk, both reachable from perfectly legal types:

  • Indexers. Type.GetProperties() includes them, and PropertyInfo.GetValue(subject) without index arguments throws TargetParameterCountException. Wolverine.Pulsar's PulsarTransport has a this[Uri] indexer, which is enough to make it undescribable.
  • Set-only properties. No getter at all; GetValue throws ArgumentException.

Proposed fix

  • Skip properties where !CanRead or GetIndexParameters().Length > 0.
  • Catch anything a getter throws (including from the [ChildDescription] / [DescribeAsStringArray] / [DescribeAsConfigurationState] branches) and record an OptionsValue.Unreadable(...) in its place — value "Could not be read -- <ExceptionTypeName>".
  • Report the exception type only, never the message: descriptions are shipped to monitoring consoles and go to some length to keep secrets out, and exception messages habitually quote the offending configuration value (ArgumentNullException on a connection string, etc.).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions