Add RecurringError class for errors that should only be logged once per session
Summary: Some errors such as UI errors should be logged whenever they occur, but some, such as those that occur when a device keeps trying to connect but can't, should not be. This adds the class and replaces the top recurring errors with it. Reviewed By: danielbuechele Differential Revision: D8639448 fbshipit-source-id: f001aa1e90eae6d26a8dbfcd3175b51fc486eae9
This commit is contained in:
committed by
Facebook Github Bot
parent
0ddeb076bb
commit
de353a7ed0
@@ -13,6 +13,7 @@ import CertificateProvider from './utils/CertificateProvider';
|
||||
import {RSocketServer, ReactiveSocket} from 'rsocket-core';
|
||||
import RSocketTCPServer from 'rsocket-tcp-server';
|
||||
import Client from './Client.js';
|
||||
import {RecurringError} from './utils/errors';
|
||||
|
||||
const EventEmitter = (require('events'): any);
|
||||
const invariant = require('invariant');
|
||||
@@ -261,10 +262,11 @@ class ConnectionTracker {
|
||||
this.connectionAttempts.set(key, entry);
|
||||
if (entry.length >= this.connectionProblemThreshold) {
|
||||
console.error(
|
||||
`Connection loop detected with ${key}. Connected ${
|
||||
entry.length
|
||||
} times in ${(time - entry[0]) / 1000}s.`,
|
||||
'ConnectionTracker',
|
||||
new RecurringError(
|
||||
`Connection loop detected with ${key}. Connected ${
|
||||
this.connectionProblemThreshold
|
||||
} times within ${this.timeWindowMillis / 1000}s.`,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
import LogManager from '../fb-stubs/Logger';
|
||||
import {RecurringError} from './errors';
|
||||
const fs = require('fs');
|
||||
const adb = require('adbkit-fb');
|
||||
import {
|
||||
@@ -82,7 +83,7 @@ export default class CertificateProvider {
|
||||
this.ensureOpenSSLIsAvailable();
|
||||
if (!appDirectory.match(allowedAppDirectoryRegex)) {
|
||||
return Promise.reject(
|
||||
new Error(
|
||||
new RecurringError(
|
||||
`Invalid appDirectory recieved from ${os} device: ${appDirectory}`,
|
||||
),
|
||||
);
|
||||
@@ -174,7 +175,7 @@ export default class CertificateProvider {
|
||||
fs.writeFileSync(destination + filename, contents);
|
||||
return Promise.resolve();
|
||||
}
|
||||
return Promise.reject(new Error(`Unsupported device os: ${os}`));
|
||||
return Promise.reject(new RecurringError(`Unsupported device os: ${os}`));
|
||||
}
|
||||
|
||||
getTargetDeviceId(
|
||||
@@ -209,7 +210,9 @@ export default class CertificateProvider {
|
||||
return Promise.all(deviceMatchList).then(devices => {
|
||||
const matchingIds = devices.filter(m => m.isMatch).map(m => m.id);
|
||||
if (matchingIds.length == 0) {
|
||||
throw new Error(`No matching device found for app: ${appName}`);
|
||||
throw new RecurringError(
|
||||
`No matching device found for app: ${appName}`,
|
||||
);
|
||||
}
|
||||
return matchingIds[0];
|
||||
});
|
||||
@@ -261,11 +264,13 @@ export default class CertificateProvider {
|
||||
command: string,
|
||||
): Promise<string> {
|
||||
if (!user.match(allowedAppNameRegex)) {
|
||||
return Promise.reject(new Error(`Disallowed run-as user: ${user}`));
|
||||
return Promise.reject(
|
||||
new RecurringError(`Disallowed run-as user: ${user}`),
|
||||
);
|
||||
}
|
||||
if (command.match(/[']/)) {
|
||||
return Promise.reject(
|
||||
new Error(`Disallowed escaping command: ${command}`),
|
||||
new RecurringError(`Disallowed escaping command: ${command}`),
|
||||
);
|
||||
}
|
||||
return this.adb
|
||||
@@ -274,14 +279,14 @@ export default class CertificateProvider {
|
||||
.then(buffer => buffer.toString())
|
||||
.then(output => {
|
||||
if (output.match(appNotDebuggableRegex)) {
|
||||
const e = new Error(
|
||||
const e = new RecurringError(
|
||||
`Android app ${user} is not debuggable. To use it with sonar, add android:debuggable="true" to the application section of AndroidManifest.xml`,
|
||||
);
|
||||
this.server.emit('error', e);
|
||||
throw e;
|
||||
}
|
||||
if (output.toLowerCase().match(operationNotPermittedRegex)) {
|
||||
const e = new Error(
|
||||
const e = new RecurringError(
|
||||
`Your android device (${deviceId}) does not support the adb shell run-as command. We're tracking this at https://github.com/facebook/Sonar/issues/92`,
|
||||
);
|
||||
this.server.emit('error', e);
|
||||
@@ -307,13 +312,13 @@ export default class CertificateProvider {
|
||||
.then(subject => {
|
||||
const matches = subject.trim().match(x509SubjectCNRegex);
|
||||
if (!matches || matches.length < 2) {
|
||||
throw new Error(`Cannot extract CN from ${subject}`);
|
||||
throw new RecurringError(`Cannot extract CN from ${subject}`);
|
||||
}
|
||||
return matches[1];
|
||||
})
|
||||
.then(appName => {
|
||||
if (!appName.match(allowedAppNameRegex)) {
|
||||
throw new Error(
|
||||
throw new RecurringError(
|
||||
`Disallowed app name in CSR: ${appName}. Only alphanumeric characters and '.' allowed.`,
|
||||
);
|
||||
}
|
||||
|
||||
14
src/utils/errors.js
Normal file
14
src/utils/errors.js
Normal file
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* Copyright 2018-present Facebook.
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
* @format
|
||||
*/
|
||||
|
||||
// Class of errors that may keep repeating but should only be logged once.
|
||||
export class RecurringError extends Error {
|
||||
constructor(message: string) {
|
||||
super(message);
|
||||
this.name = 'RecurringError';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user