-
-
Notifications
You must be signed in to change notification settings - Fork 201
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
[json-rpc-engine] Fix any types in catch blocks, refactor #3906
Changes from 15 commits
af6ffbc
49327db
c81e0cc
6f9f1e2
8854416
8d2a9d1
145570f
4b61631
bac8e0e
b9549ed
4c631d2
950237e
77b2c92
ed282d8
45a318e
e8f7892
b1b3d1b
97214c2
cfaa18b
b8bbdaa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -9,21 +9,23 @@ import type { | |||||||||||||||||||||||||||
JsonRpcParams, | ||||||||||||||||||||||||||||
PendingJsonRpcResponse, | ||||||||||||||||||||||||||||
} from '@metamask/utils'; | ||||||||||||||||||||||||||||
import { hasProperty, isJsonRpcRequest } from '@metamask/utils'; | ||||||||||||||||||||||||||||
import { | ||||||||||||||||||||||||||||
hasProperty, | ||||||||||||||||||||||||||||
isJsonRpcNotification, | ||||||||||||||||||||||||||||
isJsonRpcRequest, | ||||||||||||||||||||||||||||
} from '@metamask/utils'; | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
export type JsonRpcEngineCallbackError = Error | SerializedJsonRpcError | null; | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
export type JsonRpcEngineReturnHandler = ( | ||||||||||||||||||||||||||||
done: (error?: JsonRpcEngineCallbackError) => void, | ||||||||||||||||||||||||||||
done: (error?: unknown) => void, | ||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. New strategy: consistently type all errors as |
||||||||||||||||||||||||||||
) => void; | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
export type JsonRpcEngineNextCallback = ( | ||||||||||||||||||||||||||||
returnHandlerCallback?: JsonRpcEngineReturnHandler, | ||||||||||||||||||||||||||||
) => void; | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
export type JsonRpcEngineEndCallback = ( | ||||||||||||||||||||||||||||
error?: JsonRpcEngineCallbackError, | ||||||||||||||||||||||||||||
) => void; | ||||||||||||||||||||||||||||
export type JsonRpcEngineEndCallback = (error?: unknown) => void; | ||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. New strategy: consistently type all errors as |
||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
export type JsonRpcMiddleware< | ||||||||||||||||||||||||||||
Params extends JsonRpcParams, | ||||||||||||||||||||||||||||
|
@@ -200,9 +202,13 @@ export class JsonRpcEngine extends SafeEventEmitter { | |||||||||||||||||||||||||||
requests: (JsonRpcRequest<Params> | JsonRpcNotification<Params>)[], | ||||||||||||||||||||||||||||
): Promise<JsonRpcResponse<Result>[]>; | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
// TODO: Replace `any` with type | ||||||||||||||||||||||||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||||||||||||||||||||||||||||
handle(req: unknown, callback?: any) { | ||||||||||||||||||||||||||||
handle( | ||||||||||||||||||||||||||||
req: | ||||||||||||||||||||||||||||
| (JsonRpcRequest | JsonRpcNotification)[] | ||||||||||||||||||||||||||||
| JsonRpcRequest | ||||||||||||||||||||||||||||
| JsonRpcNotification, | ||||||||||||||||||||||||||||
callback?: (error: unknown, response: never) => void, | ||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||||||||||||||||||||||||||||
) { | ||||||||||||||||||||||||||||
this.#assertIsNotDestroyed(); | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
if (callback && typeof callback !== 'function') { | ||||||||||||||||||||||||||||
|
@@ -211,15 +217,24 @@ export class JsonRpcEngine extends SafeEventEmitter { | |||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
if (Array.isArray(req)) { | ||||||||||||||||||||||||||||
if (callback) { | ||||||||||||||||||||||||||||
return this.#handleBatch(req, callback); | ||||||||||||||||||||||||||||
return this.#handleBatch( | ||||||||||||||||||||||||||||
req, | ||||||||||||||||||||||||||||
callback as ( | ||||||||||||||||||||||||||||
error: unknown, | ||||||||||||||||||||||||||||
responses?: JsonRpcResponse<Json>[], | ||||||||||||||||||||||||||||
) => void, | ||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||
return this.#handleBatch(req); | ||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
if (callback) { | ||||||||||||||||||||||||||||
return this.#handle(req as JsonRpcRequest, callback); | ||||||||||||||||||||||||||||
return this.#handle( | ||||||||||||||||||||||||||||
req, | ||||||||||||||||||||||||||||
callback as (error: unknown, response?: JsonRpcResponse<Json>) => void, | ||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The first and second overload signatures of |
||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||
return this._promiseHandle(req as JsonRpcRequest); | ||||||||||||||||||||||||||||
return this._promiseHandle(req); | ||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||
|
@@ -239,23 +254,19 @@ export class JsonRpcEngine extends SafeEventEmitter { | |||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
if (isComplete) { | ||||||||||||||||||||||||||||
await JsonRpcEngine.#runReturnHandlers(returnHandlers); | ||||||||||||||||||||||||||||
return end(middlewareError as JsonRpcEngineCallbackError); | ||||||||||||||||||||||||||||
return end(middlewareError); | ||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises | ||||||||||||||||||||||||||||
return next(async (handlerCallback) => { | ||||||||||||||||||||||||||||
try { | ||||||||||||||||||||||||||||
await JsonRpcEngine.#runReturnHandlers(returnHandlers); | ||||||||||||||||||||||||||||
// TODO: Replace `any` with type | ||||||||||||||||||||||||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||||||||||||||||||||||||||||
} catch (error: any) { | ||||||||||||||||||||||||||||
} catch (error) { | ||||||||||||||||||||||||||||
return handlerCallback(error); | ||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||
return handlerCallback(); | ||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||
// TODO: Replace `any` with type | ||||||||||||||||||||||||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||||||||||||||||||||||||||||
} catch (error: any) { | ||||||||||||||||||||||||||||
} catch (error) { | ||||||||||||||||||||||||||||
return end(error); | ||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||
|
@@ -317,8 +328,8 @@ export class JsonRpcEngine extends SafeEventEmitter { | |||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||
).filter( | ||||||||||||||||||||||||||||
// Filter out any notification responses. | ||||||||||||||||||||||||||||
(response) => response !== undefined, | ||||||||||||||||||||||||||||
) as JsonRpcResponse<Json>[]; | ||||||||||||||||||||||||||||
(response): response is JsonRpcResponse<Json> => response !== undefined, | ||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice! Good example usage of this. |
||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
// 3. Return batch response | ||||||||||||||||||||||||||||
if (callback) { | ||||||||||||||||||||||||||||
|
@@ -392,7 +403,7 @@ export class JsonRpcEngine extends SafeEventEmitter { | |||||||||||||||||||||||||||
const error = new JsonRpcError( | ||||||||||||||||||||||||||||
errorCodes.rpc.invalidRequest, | ||||||||||||||||||||||||||||
`Must specify a string method. Received: ${typeof callerReq.method}`, | ||||||||||||||||||||||||||||
{ request: callerReq as Json }, | ||||||||||||||||||||||||||||
{ request: callerReq }, | ||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
if (this.#notificationHandler && !isJsonRpcRequest(callerReq)) { | ||||||||||||||||||||||||||||
|
@@ -403,25 +414,23 @@ export class JsonRpcEngine extends SafeEventEmitter { | |||||||||||||||||||||||||||
return callback(error, { | ||||||||||||||||||||||||||||
// Typecast: This could be a notification, but we want to access the | ||||||||||||||||||||||||||||
// `id` even if it doesn't exist. | ||||||||||||||||||||||||||||
id: (callerReq as JsonRpcRequest).id ?? null, | ||||||||||||||||||||||||||||
id: (callerReq as JsonRpcRequest).id, | ||||||||||||||||||||||||||||
jsonrpc: '2.0', | ||||||||||||||||||||||||||||
error, | ||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
// Handle notifications. | ||||||||||||||||||||||||||||
// We can't use isJsonRpcNotification here because that narrows callerReq to | ||||||||||||||||||||||||||||
// "never" after the if clause for unknown reasons. | ||||||||||||||||||||||||||||
if (this.#notificationHandler && !isJsonRpcRequest(callerReq)) { | ||||||||||||||||||||||||||||
} else if ( | ||||||||||||||||||||||||||||
this.#notificationHandler && | ||||||||||||||||||||||||||||
isJsonRpcNotification(callerReq) && | ||||||||||||||||||||||||||||
!isJsonRpcRequest(callerReq) | ||||||||||||||||||||||||||||
Comment on lines
+425
to
+426
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||||||||||||||||||||||||||||
) { | ||||||||||||||||||||||||||||
try { | ||||||||||||||||||||||||||||
await this.#notificationHandler(callerReq); | ||||||||||||||||||||||||||||
} catch (error) { | ||||||||||||||||||||||||||||
return callback(error); | ||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||
return callback(null); | ||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
let error: JsonRpcEngineCallbackError = null; | ||||||||||||||||||||||||||||
let error = null; | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
// Handle requests. | ||||||||||||||||||||||||||||
// Typecast: Permit missing id's for backwards compatibility. | ||||||||||||||||||||||||||||
|
@@ -433,9 +442,7 @@ export class JsonRpcEngine extends SafeEventEmitter { | |||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
try { | ||||||||||||||||||||||||||||
await JsonRpcEngine.#processRequest(req, res, this.#middleware); | ||||||||||||||||||||||||||||
// TODO: Replace `any` with type | ||||||||||||||||||||||||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||||||||||||||||||||||||||||
} catch (_error: any) { | ||||||||||||||||||||||||||||
} catch (_error) { | ||||||||||||||||||||||||||||
// A request handler error, a re-thrown middleware error, or something | ||||||||||||||||||||||||||||
// unexpected. | ||||||||||||||||||||||||||||
error = _error; | ||||||||||||||||||||||||||||
|
@@ -543,13 +550,13 @@ export class JsonRpcEngine extends SafeEventEmitter { | |||||||||||||||||||||||||||
returnHandlers: JsonRpcEngineReturnHandler[], | ||||||||||||||||||||||||||||
): Promise<[unknown, boolean]> { | ||||||||||||||||||||||||||||
return new Promise((resolve) => { | ||||||||||||||||||||||||||||
const end: JsonRpcEngineEndCallback = (error?: unknown) => { | ||||||||||||||||||||||||||||
const end: JsonRpcEngineEndCallback = (error) => { | ||||||||||||||||||||||||||||
const parsedError = error || response.error; | ||||||||||||||||||||||||||||
if (parsedError) { | ||||||||||||||||||||||||||||
response.error = serializeError(parsedError); | ||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||
// True indicates that the request should end | ||||||||||||||||||||||||||||
resolve([parsedError, true]); | ||||||||||||||||||||||||||||
resolve([parsedError ?? null, true]); | ||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems that we are converting
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for catching this. It's no longer necessary now that Applied here: cfaa18b, except I didn't add the |
||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
const next: JsonRpcEngineNextCallback = ( | ||||||||||||||||||||||||||||
|
@@ -567,7 +574,7 @@ export class JsonRpcEngine extends SafeEventEmitter { | |||||||||||||||||||||||||||
`Received "${typeof returnHandler}" for request:\n${jsonify( | ||||||||||||||||||||||||||||
request, | ||||||||||||||||||||||||||||
)}`, | ||||||||||||||||||||||||||||
{ request: request as Json }, | ||||||||||||||||||||||||||||
{ request }, | ||||||||||||||||||||||||||||
), | ||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||
|
@@ -581,9 +588,7 @@ export class JsonRpcEngine extends SafeEventEmitter { | |||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
try { | ||||||||||||||||||||||||||||
middleware(request, response, next, end); | ||||||||||||||||||||||||||||
// TODO: Replace `any` with type | ||||||||||||||||||||||||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||||||||||||||||||||||||||||
} catch (error: any) { | ||||||||||||||||||||||||||||
} catch (error) { | ||||||||||||||||||||||||||||
end(error); | ||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||
|
@@ -625,15 +630,15 @@ export class JsonRpcEngine extends SafeEventEmitter { | |||||||||||||||||||||||||||
`JsonRpcEngine: Response has no error or result for request:\n${jsonify( | ||||||||||||||||||||||||||||
request, | ||||||||||||||||||||||||||||
)}`, | ||||||||||||||||||||||||||||
{ request: request as Json }, | ||||||||||||||||||||||||||||
{ request }, | ||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
if (!isComplete) { | ||||||||||||||||||||||||||||
throw new JsonRpcError( | ||||||||||||||||||||||||||||
errorCodes.rpc.internal, | ||||||||||||||||||||||||||||
`JsonRpcEngine: Nothing ended request:\n${jsonify(request)}`, | ||||||||||||||||||||||||||||
{ request: request as Json }, | ||||||||||||||||||||||||||||
{ request }, | ||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,7 +5,10 @@ import type { | |
PendingJsonRpcResponse, | ||
} from '@metamask/utils'; | ||
|
||
import type { JsonRpcMiddleware } from './JsonRpcEngine'; | ||
import type { | ||
JsonRpcEngineReturnHandler, | ||
JsonRpcMiddleware, | ||
} from './JsonRpcEngine'; | ||
|
||
export type AsyncJsonRpcEngineNextCallback = () => Promise<void>; | ||
|
||
|
@@ -18,7 +21,7 @@ export type AsyncJsonrpcMiddleware< | |
next: AsyncJsonRpcEngineNextCallback, | ||
) => Promise<void>; | ||
|
||
type ReturnHandlerCallback = (error: null | Error) => void; | ||
type ReturnHandlerCallback = Parameters<JsonRpcEngineReturnHandler>[0]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This definition is responsive to changes in |
||
|
||
/** | ||
* JsonRpcEngine only accepts callback-based middleware directly. | ||
|
@@ -83,9 +86,7 @@ export function createAsyncMiddleware< | |
} else { | ||
end(null); | ||
} | ||
// TODO: Replace `any` with type | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
} catch (error: any) { | ||
} catch (error) { | ||
if (returnHandlerCallback) { | ||
(returnHandlerCallback as ReturnHandlerCallback)(error); | ||
} else { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
JsonRpcEngineCallbackError
is no longer used anywhere in core or extension. Mobile has two instances inRPCMethodMiddleware.ts
.