Skip to content

Commit

Permalink
Improve rpc errors logging and removing user rejected errors (#2564)
Browse files Browse the repository at this point in the history
* Improve rpc errors logging and removing user rejected errors

* Update for even more cases

* Add comments to code

* Add trackErrorAsAnalytics

* Use typeof
  • Loading branch information
andrepimenta authored May 4, 2021
1 parent 90ffa8c commit 474b77b
Showing 1 changed file with 71 additions and 3 deletions.
74 changes: 71 additions & 3 deletions app/util/middlewares.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
import Logger from './Logger';
import { trackErrorAsAnalytics } from './analyticsV2';

const REJECTED_TRANSACTION_ERROR = 'User rejected the transaction';
/**
* List of rpc errors caused by the user rejecting a certain action.
* Errors that include these phrases should not be logged to Sentry.
* Examples of these errors include:
* - User rejected the transaction
* - User cancelled the transaction
* - User rejected the request.
* - MetaMask Message Signature: User denied message signature.
* - MetaMask Personal Message Signature: User denied message signature.
*/
const USER_REJECTED_ERRORS = ['user rejected', 'user denied', 'user cancelled'];

const USER_REJECTED_ERROR_CODE = 4001;

/**
* Returns a middleware that appends the DApp origin to request
Expand All @@ -21,6 +34,29 @@ export function createOriginMiddleware(opts) {
};
}

/**
* Checks if the error code or message contains a user rejected error
* @param {String} errorMessage
* @returns {boolean}
*/
function containsUserRejectedError(errorMessage, errorCode) {
try {
if (!errorMessage || !(typeof errorMessage === 'string')) return false;

const userRejectedErrorMessage = USER_REJECTED_ERRORS.some(userRejectedError =>
errorMessage.toLowerCase().includes(userRejectedError.toLowerCase())
);

if (userRejectedErrorMessage) return true;

if (errorCode === USER_REJECTED_ERROR_CODE) return true;

return false;
} catch (e) {
return false;
}
}

/**
* Returns a middleware that logs RPC activity
* @param {{ origin: string }} opts - The middleware options
Expand All @@ -31,8 +67,40 @@ export function createLoggerMiddleware(opts) {
next((/** @type {Function} */ cb) => {
if (res.error) {
const { error, ...resWithoutError } = res;
if (error && error.message !== REJECTED_TRANSACTION_ERROR) {
Logger.error(error, { message: 'Error in RPC response', res: resWithoutError });
if (error) {
if (containsUserRejectedError(error.message, error.code)) {
trackErrorAsAnalytics(`Error in RPC response: User rejected`, error.message);
} else {
/**
* Example of a rpc error:
* { "code":-32603,
* "message":"Internal JSON-RPC error.",
* "data":{"code":-32000,"message":"gas required exceeds allowance (59956966) or always failing transaction"}
* }
* This will make the error log to sentry with the title "gas required exceeds allowance (59956966) or always failing transaction"
* making it easier to differentiate each error.
*/
let errorToLog = error;
const errorParams = {
message: 'Error in RPC response',
orginalError: error,
res: resWithoutError
};

if (error.message) {
errorToLog = new Error(error.message);
}

if (error.data) {
errorParams.data = error.data;

if (error.data.message) {
errorToLog = new Error(error.data.message);
}
}

Logger.error(errorToLog, errorParams);
}
}
}
if (req.isMetamaskInternal) {
Expand Down

0 comments on commit 474b77b

Please sign in to comment.