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:
John Knox
2018-07-05 07:06:57 -07:00
committed by Facebook Github Bot
parent 0ddeb076bb
commit de353a7ed0
3 changed files with 34 additions and 13 deletions

View File

@@ -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.`,
),
);
}
}

View File

@@ -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
View 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';
}
}