Skip to content
This repository has been archived by the owner on Jul 29, 2024. It is now read-only.

Commit

Permalink
chore(cleanup): clean up per comments
Browse files Browse the repository at this point in the history
* use the thrown error for stack traces instead of creating a new one
* use inheritance over creating a new error
* read in stacktrace with captureStackTrace
* removed default error messages
  • Loading branch information
cnishina committed Jun 13, 2016
1 parent 83b4d4a commit d4c13bb
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 40 deletions.
70 changes: 51 additions & 19 deletions lib/exitCodes.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,73 @@
import {Logger} from './logger2';

const CONFIG_ERROR_CODE = 105;
const BROWSER_ERROR_CODE = 135;
const BROWSER_CONNECT_ERROR_CODE = 135;
const KITCHEN_SINK_CODE = 199;

export class ProtractorError extends Error {
static ERR_MSGS: string[];
static DEFAULT_MSG = 'protractor encountered an error';
static CODE = KITCHEN_SINK_CODE;

error: Error;
description: string;
message: string; // a one liner, if more than one line is sent, it will be cut off
stack: string; // has the message with the stack trace
code: number;
stack: string;
constructor(logger: Logger, description: string, code: number) {
super();
this.error = new Error();
this.code = code;
this.description = description;
this.stack = this.error.stack;

/**
* Captures the stack trace to this.stack from the Error.captureStackTrace.
* this allows us to capture the error of this error object. Note:
* called with Error set to any to quiet typescript warnings.
*/
captureStackTrace() {
(Error as any).captureStackTrace(this, this.constructor);
}

constructor(logger: Logger, message?: string, code?: number, error?: Error) {
super(message ? message : ProtractorError.DEFAULT_MSG);
if (message) {
this.message = message;
} else {
this.message = ProtractorError.DEFAULT_MSG;
}

if (code) {
this.code = code;
} else {
this.code = ProtractorError.CODE;
}

if (error) {
this.error = error;
}
this.captureStackTrace();
this.logError(logger);
process.exit(this.code);
}

logError(logger: Logger) {
logger.error('error code: ' + this.code);
logger.error('description: ' + this.description);
logger.error(this.stack);
ProtractorError.log(logger, this.code, this.message, this.stack);
}

static log(logger: Logger, code: number, message: string, stack: string) {
let messages = message.split('\n');
if (messages.length > 1) {
message = messages[0];
}
logger.error('Error code: ' + code);
logger.error('Error message: ' + message);
logger.error(stack);
}
}

/**
* Configuration file error
*/
export class ConfigError extends ProtractorError {
static DEFAULT_MSG = 'configuration error';
static CODE = CONFIG_ERROR_CODE;
constructor(logger: Logger, opt_msg?: string) {
super(logger, opt_msg || ConfigError.DEFAULT_MSG, ConfigError.CODE);
process.exit(ConfigError.CODE);
constructor(logger: Logger, opt_msg?: string, error?: Error) {
super(logger, opt_msg || ConfigError.DEFAULT_MSG, ConfigError.CODE, error);
}
}

Expand All @@ -43,14 +76,13 @@ export class ConfigError extends ProtractorError {
*/
export class BrowserError extends ProtractorError {
static DEFAULT_MSG = 'browser error';
static CODE = BROWSER_ERROR_CODE;
static CODE = BROWSER_CONNECT_ERROR_CODE;
static ERR_MSGS = [
'ECONNREFUSED connect ECONNREFUSED', 'Sauce Labs Authentication Error',
'Invalid username or password'
];
constructor(logger: Logger, opt_msg?: string) {
super(logger, opt_msg || BrowserError.DEFAULT_MSG, BrowserError.CODE);
process.exit(BrowserError.CODE);
constructor(logger: Logger, opt_msg?: string, error?: Error) {
super(logger, opt_msg || BrowserError.DEFAULT_MSG, BrowserError.CODE, error);
}
}

Expand Down
11 changes: 6 additions & 5 deletions lib/launcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/
import * as q from 'q';
import {Config, ConfigParser} from './configParser';
import {ConfigError, ErrorHandler} from './exitCodes';
import {ProtractorError, ConfigError, ErrorHandler} from './exitCodes';
import {Logger} from './logger2';
import {Runner} from './runner';
import {TaskRunner} from './taskRunner';
Expand Down Expand Up @@ -180,15 +180,16 @@ let initFn = function(configFile: string, additionalConfig: Config) {
process.on('uncaughtException', (e: Error) => {
let errorCode = ErrorHandler.parseError(e);
if (errorCode) {
logger.error(e.stack);
let protractorError = e as ProtractorError;
ProtractorError.log(logger, errorCode, protractorError.message, protractorError.stack);
process.exit(errorCode);
} else {
logger.error(e.stack);
logger.error('"process.on(\'uncaughtException\'" error, see launcher');
process.exit(ProtractorError.CODE);
}
});

process.on('exit', (code: number) => {
console.log(code);
if (code) {
logger.error('Process exited with error code ' + code);
} else if (scheduler.numTasksOutstanding() > 0) {
Expand Down Expand Up @@ -254,7 +255,7 @@ let initFn = function(configFile: string, additionalConfig: Config) {
' instance(s) of WebDriver still running');
})
.catch((err: Error) => {
logger.error('Error:', err.stack || err.message || err);
logger.error('Error:', (err as any).stack || err.message || err);
cleanUpAndExit(RUNNERS_FAILED_EXIT_CODE);
});
}
Expand Down
36 changes: 20 additions & 16 deletions lib/ptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ import {Browser, ElementHelper} from './browser';
import {ProtractorBy} from './locators';
import {ElementFinder, ElementArrayFinder} from './element';
import * as EC from './expectedConditions';
import {Promise} from './selenium-webdriver/promise';

let SeleniumWebdriverActions = require('selenium-webdriver/lib/actions');
let SeleniumWebdriverInput = require('selenium-webdriver/lib/input');
let SeleniumWebdriverPromise = require('selenium-webdriver/lib/promise');
let SeleniumWebdriverCommand = require('selenium-webdriver/lib/command');

export namespace protractor {
export let browser: Browser;
Expand All @@ -20,21 +24,21 @@ export namespace protractor {
export let wrapDriver: Function;
export let ExpectedConditions = new EC.ExpectedConditions();
export let promise = {
controlFlow: require('selenium-webdriver/lib/promise').controlFlow,
createFlow: require('selenium-webdriver/lib/promise').createFlow,
defer: require('selenium-webdriver/lib/promise').defer,
delayed: require('selenium-webdriver/lib/promise').delayed,
filter: require('selenium-webdriver/lib/promise').filter,
fulfilled: require('selenium-webdriver/lib/promise').fulfilled,
fullyResolved: require('selenium-webdriver/lib/promise').fullyResolved,
isPromise: require('selenium-webdriver/lib/promise').isPromise,
rejected: require('selenium-webdriver/lib/promise').rejected,
thenFinally: require('selenium-webdriver/lib/promise').thenFinally,
when: require('selenium-webdriver/lib/promise').when
controlFlow: SeleniumWebdriverPromise.controlFlow,
createFlow: SeleniumWebdriverPromise.createFlow,
defer: SeleniumWebdriverPromise.defer,
delayed: SeleniumWebdriverPromise.delayed,
filter: SeleniumWebdriverPromise.filter,
fulfilled: SeleniumWebdriverPromise.fulfilled,
fullyResolved: SeleniumWebdriverPromise.fullyResolved,
isPromise: SeleniumWebdriverPromise.isPromise,
rejected: SeleniumWebdriverPromise.rejected,
thenFinally: SeleniumWebdriverPromise.thenFinally,
when: SeleniumWebdriverPromise.when
};
export let ActionSequence = require('selenium-webdriver/lib/actions').ActionSequence;
export let Key = require('selenium-webdriver/lib/input').Key;
export let ActionSequence = SeleniumWebdriverActions.ActionSequence;
export let Key = SeleniumWebdriverInput.Key;

export let Command = require('selenium-webdriver/lib/command').Command;
export let CommandName = require('selenium-webdriver/lib/command').Name;
export let Command = SeleniumWebdriverCommand.Command;
export let CommandName = SeleniumWebdriverCommand.Name;
}

0 comments on commit d4c13bb

Please sign in to comment.