Skip to content

Add error property to "degraded" events #6188

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

Open
wants to merge 11 commits into
base: main
Choose a base branch
from

Conversation

mcmire
Copy link
Contributor

@mcmire mcmire commented Jul 24, 2025

Explanation

We would like to start tracking the HTTP status code in metrics when the NetworkController:rpcEndpointDegraded event is published because the maximum number of retries for a request has been exceeded. The HTTP status is stored in the error that Cockatiel captures, so we just need to include it in the event payload.

References

Closes #6190.

Checklist

@mcmire
Copy link
Contributor Author

mcmire commented Jul 24, 2025

@metamaskbot publish-previews

Copy link
Contributor

Preview builds have been published. See these instructions for more information about preview builds.

Expand for full list of packages and versions.
{
  "@metamask-previews/account-tree-controller": "0.6.0-preview-889b5df9",
  "@metamask-previews/accounts-controller": "32.0.0-preview-889b5df9",
  "@metamask-previews/address-book-controller": "6.1.1-preview-889b5df9",
  "@metamask-previews/announcement-controller": "7.0.3-preview-889b5df9",
  "@metamask-previews/app-metadata-controller": "1.0.0-preview-889b5df9",
  "@metamask-previews/approval-controller": "7.1.3-preview-889b5df9",
  "@metamask-previews/assets-controllers": "73.0.0-preview-889b5df9",
  "@metamask-previews/base-controller": "8.0.1-preview-889b5df9",
  "@metamask-previews/bridge-controller": "37.0.0-preview-889b5df9",
  "@metamask-previews/bridge-status-controller": "37.0.0-preview-889b5df9",
  "@metamask-previews/build-utils": "3.0.3-preview-889b5df9",
  "@metamask-previews/chain-agnostic-permission": "1.0.0-preview-889b5df9",
  "@metamask-previews/composable-controller": "11.0.0-preview-889b5df9",
  "@metamask-previews/controller-utils": "11.11.0-preview-889b5df9",
  "@metamask-previews/delegation-controller": "0.6.0-preview-889b5df9",
  "@metamask-previews/earn-controller": "4.0.0-preview-889b5df9",
  "@metamask-previews/eip1193-permission-middleware": "1.0.0-preview-889b5df9",
  "@metamask-previews/ens-controller": "17.0.1-preview-889b5df9",
  "@metamask-previews/error-reporting-service": "2.0.0-preview-889b5df9",
  "@metamask-previews/eth-json-rpc-provider": "4.1.8-preview-889b5df9",
  "@metamask-previews/foundryup": "1.0.0-preview-889b5df9",
  "@metamask-previews/gas-fee-controller": "24.0.0-preview-889b5df9",
  "@metamask-previews/json-rpc-engine": "10.0.3-preview-889b5df9",
  "@metamask-previews/json-rpc-middleware-stream": "8.0.7-preview-889b5df9",
  "@metamask-previews/keyring-controller": "22.1.0-preview-889b5df9",
  "@metamask-previews/logging-controller": "6.0.4-preview-889b5df9",
  "@metamask-previews/message-manager": "12.0.2-preview-889b5df9",
  "@metamask-previews/messenger": "0.0.0-preview-889b5df9",
  "@metamask-previews/multichain-account-service": "0.2.1-preview-889b5df9",
  "@metamask-previews/multichain-api-middleware": "1.0.0-preview-889b5df9",
  "@metamask-previews/multichain-network-controller": "0.11.0-preview-889b5df9",
  "@metamask-previews/multichain-transactions-controller": "4.0.0-preview-889b5df9",
  "@metamask-previews/name-controller": "8.0.3-preview-889b5df9",
  "@metamask-previews/network-controller": "24.0.1-preview-889b5df9",
  "@metamask-previews/notification-services-controller": "15.0.0-preview-889b5df9",
  "@metamask-previews/permission-controller": "11.0.6-preview-889b5df9",
  "@metamask-previews/permission-log-controller": "4.0.0-preview-889b5df9",
  "@metamask-previews/phishing-controller": "13.1.0-preview-889b5df9",
  "@metamask-previews/polling-controller": "14.0.0-preview-889b5df9",
  "@metamask-previews/preferences-controller": "18.4.1-preview-889b5df9",
  "@metamask-previews/profile-sync-controller": "22.0.0-preview-889b5df9",
  "@metamask-previews/rate-limit-controller": "6.0.3-preview-889b5df9",
  "@metamask-previews/remote-feature-flag-controller": "1.6.0-preview-889b5df9",
  "@metamask-previews/sample-controllers": "1.0.0-preview-889b5df9",
  "@metamask-previews/seedless-onboarding-controller": "2.4.0-preview-889b5df9",
  "@metamask-previews/selected-network-controller": "23.0.0-preview-889b5df9",
  "@metamask-previews/signature-controller": "32.0.0-preview-889b5df9",
  "@metamask-previews/token-search-discovery-controller": "3.3.0-preview-889b5df9",
  "@metamask-previews/transaction-controller": "59.0.0-preview-889b5df9",
  "@metamask-previews/user-operation-controller": "38.0.0-preview-889b5df9"
}

@mcmire mcmire changed the title WIP - Add error to NetworkController:rpcEndpointDegraded Add error property to "degraded" events Jul 24, 2025
[Data] extends [void]
? (data: AdditionalData) => void
: (data: Data & AdditionalData) => void
? (data: Data extends void ? AdditionalData : Data & AdditionalData) => void
Copy link
Contributor Author

@mcmire mcmire Aug 11, 2025

Choose a reason for hiding this comment

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

This was an interesting one to figure out.

The purpose of this utility type is to extend the type for a Cockatiel event with additional payload data. We need to do this because NetworkController:rpcEndpointDegraded and NetworkController:rpcEndpointAvailable are based on existing Cockatiel events but with additional properties we add.

However, this type did not properly account for when EventListener was CockatielEvent<FailureReason<unknown> | void> (which is the same thing as saying (data: void | { error: Error } | { value: unknown }) => void).

If we say the following

AddToCockatielEventData<
  (data: void | { error: Error } | { value: unknown }) => void,
  { foo: 'bar' }
>

we want this to resolve to:

(data: { foo: 'bar' } | ({ error: Error } & { foo: 'bar' }) | ({ value: unknown } & { foo: 'bar' })) => void

(Essentially, we want the void to be treated as {}.)

But instead this was resolving as:

(data: ((void | { error: Error } | { value: unknown }) & { foo: 'bar' }) => void

which distributes to:

(data: (void & { foo: 'bar' }) | ({ error: Error } & { foo: 'bar' }) | ({ value: unknown } & { foo: 'bar' })) => void

This is incorrect, because void & { foo: 'bar' } doesn't make sense.

What we want is for TypeScript to distribute void | { error: Error } | { value: unknown } over the condition. So first, despite the comment here, we don't want [Data] extends [void], because that prevents TypeScript from applying the distribution.

But the second thing is that even if we say Data extends void then TypeScript still won't apply the distribution, because the condition is actually in the wrong place. What we want is not a type union of three function types, but a single type with a type union for the arguments.

Even if the condition were in the place we wanted it, TypeScript seems to distribute the type union only in a particular circumstance. Looking a bit deeper at the TypeScript 2.8 release notes where this concept was introduced, it says: "Distributive conditional types are automatically distributed over union types during instantiation." In this case, we also need to place the condition so it becomes a part of the type that we want to "return" from this utility type and is not used to simply determine the return type. This way TypeScript evaluates the condition when that return type is used and not beforehand.

@mcmire mcmire marked this pull request as ready for review August 11, 2025 21:41
@mcmire mcmire requested review from a team as code owners August 11, 2025 21:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add error property to NetworkController:rpcEndpointDegraded
1 participant