Update error handling

This commit is contained in:
Kegan Myers 2014-03-04 16:51:55 -06:00
parent a7ce48782c
commit 7a6044525c
9 changed files with 115 additions and 28 deletions

View file

@ -2,19 +2,44 @@ module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-karma');
grunt.loadNpmTasks('grunt-typescript');
var sauceConf = {
linux: {opera: {low: 12, high: 12}, googlechrome: {low: 26, high: 32}, firefox: {low: 3, high: 27}},
"OS X 10.9": {googlechrome: {low: 31, high: 31}, firefox: {low: 4, high: 26}},
"OS X 10.8": {googlechrome: {low: 27, high: 32}, safari: {low: 6, high: 6}},
"OS X 10.6": {googlechrome: {low: 27, high: 32}, safari: {low: 5, high: 5}, firefox: {low: 3, high: 27}},
"Windows XP": {googlechrome: {low: 26, high: 32}, safari: {low: 3, high: 5}, opera: {low: 9, high: 12}, firefox: {low: 4, high: 27}},
"Windows 7": {googlechrome: {low: 26, high: 32}, safari: {low: 5, high: 5}, opera: {low: 9, high: 12}, firefox: {low: 4, high: 27}},
"Windows 8": {googlechrome: {low: 26, high: 32}, opera: {low: 9, high: 10}, firefox: {low: 4, high: 27}},
"Windows 8.1": {googlechrome: {low: 26, high: 32}, opera: {low: 9, high: 10}, firefox: {low: 4, high: 27}}
};
var sauceBrowsers = [];
for (var operatingSystem in sauceConf) {
for (var browser in sauceConf[operatingSystem]) {
for (var i = sauceConf[operatingSystem][browser].low; i < sauceConf[operatingSystem][browser].high; i++) {
sauceBrowsers.push((operatingSystem + "_" + browser + "_" + i).toLowerCase().replace(" ", "-"));
}
}
}
//TODO integrate with Sauce
var travisBrowsers = [];//sauceBrowsers.slice(0);
travisBrowsers.push("PhantomJS");
grunt.initConfig({
karma: {
phantom: {
local: {
configFile: "karma.conf.js",
singleRun: true,
browsers: ["PhantomJS"]
browsers: ["Chrome", "PhantomJS"]
},
chrome: {
travis: {
configFile: "karma.conf.js",
singleRun: true,
browsers: ["Chrome"]
browsers: travisBrowsers
},
watch: {
autoWatch: true,
configFile: "karma.conf.js",
browsers: ["PhantomJS", "Chrome"]
}
@ -34,5 +59,5 @@ module.exports = function (grunt) {
grunt.registerTask('default', ['typescript']);
grunt.registerTask('test', ['typescript', 'karma:phantom', 'karma:chrome']);
grunt.registerTask('test:travis', ['typescript', 'karma:phantom']);
grunt.registerTask('test:travis', ['typescript', 'karma:travis']);
};

View file

@ -12,7 +12,6 @@ Usage
Todo
----
- More robust error handling
- IE 8-9 CORS support (XDomain)
- Integrate with Sauce Labs
@ -30,6 +29,10 @@ This project is licensed under the MIT license, the text of which can be read in
Changelog
---------
####0.4.0
- Modify how exceptions are handled
- Steps toward Sauce integration
####0.3.3
- Fix Post methods actually calling GET

View file

@ -36,7 +36,7 @@ declare module Typertext {
}
}
declare module Typertext.Http {
class HttpException extends BaseException<HttpResponseStatus> {
class HttpException extends BaseException<HttpResponse> {
}
}
declare module Typertext.Http {

View file

@ -117,26 +117,32 @@ var Typertext;
if (typeof postData === "undefined") { postData = {}; }
if (typeof callback === "undefined") { callback = function (c) {
}; }
var noop = function (i) {
return "";
};
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
var getHeader = function (name) {
return xhr.getResponseHeader(name);
};
if (xhr.status == 200) {
callback(new Typertext.Http.HttpResponse(0 /* success */, getHeader, xhr.status, xhr.responseText));
} else if (xhr.status >= 400 && xhr.status < 500) {
throw new Typertext.Http.HttpException("Error type is unimplemented", -1, 2 /* clientError */);
throw new Typertext.Http.HttpException("The server returned an error response state", xhr.status, new Typertext.Http.HttpResponse(2 /* clientError */, getHeader, xhr.status, xhr.responseText));
} else if (xhr.status >= 500 && xhr.status < 600) {
throw new Typertext.Http.HttpException("Error type is unimplemented", -1, 1 /* serverError */);
} else {
throw new Typertext.Http.HttpException("An unknown error has occurred", -2, 4 /* unknownError */);
throw new Typertext.Http.HttpException("The server returned an error response state", xhr.status, new Typertext.Http.HttpResponse(1 /* serverError */, getHeader, xhr.status, xhr.responseText));
}
throw new Typertext.Http.HttpException("An unknown error has occurred", -2, new Typertext.Http.HttpResponse(4 /* unknownError */, getHeader, xhr.status, xhr.responseText));
}
};
xhr.ontimeout = function () {
callback(new Typertext.Http.HttpResponse(5 /* timeout */));
throw new Typertext.Http.HttpException("The server took too long to respond to our request", -1, new Typertext.Http.HttpResponse(5 /* timeout */, noop, -1, ""));
};
xhr.open(Typertext.Http.HttpMethod[method], request.ToString(), true);
@ -147,6 +153,7 @@ var Typertext;
}
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send(Typertext.Http.HttpUrl.UrlEncodeObject(postData));
};
return HttpRequest;

File diff suppressed because one or more lines are too long

View file

@ -1,10 +1,46 @@
module.exports = function (config) {
var sauceConf = {
linux: {opera: {low: 12, high: 12}, googlechrome: {low: 26, high: 32}, firefox: {low: 3, high: 27}},
"OS X 10.9": {googlechrome: {low: 31, high: 31}, firefox: {low: 4, high: 26}},
"OS X 10.8": {googlechrome: {low: 27, high: 32}, safari: {low: 6, high: 6}},
"OS X 10.6": {googlechrome: {low: 27, high: 32}, safari: {low: 5, high: 5}, firefox: {low: 3, high: 27}},
"Windows XP": {googlechrome: {low: 26, high: 32}, safari: {low: 3, high: 5}, opera: {low: 9, high: 12}, firefox: {low: 4, high: 27}},
"Windows 7": {googlechrome: {low: 26, high: 32}, safari: {low: 5, high: 5}, opera: {low: 9, high: 12}, firefox: {low: 4, high: 27}},
"Windows 8": {googlechrome: {low: 26, high: 32}, opera: {low: 9, high: 10}, firefox: {low: 4, high: 27}},
"Windows 8.1": {googlechrome: {low: 26, high: 32}, opera: {low: 9, high: 10}, firefox: {low: 4, high: 27}}
};
var sauceBrowsers = {};
for (var operatingSystem in sauceConf) {
for (var browser in sauceConf[operatingSystem]) {
for (var i = sauceConf[operatingSystem][browser].low; i < sauceConf[operatingSystem][browser].high; i++) {
sauceBrowsers[(operatingSystem + "_" + browser + "_" + i).toLowerCase().replace(" ", "-")] = {
base: "SauceLabs",
browserName: browser,
platform: operatingSystem,
version: "" + i
}
}
}
}
config.set({
sauceLabs: {
startConnect: true,
testName: 'TypertextTests',
recordScreenshots: false
},
basePath: __dirname,
frameworks: ['jasmine'],
files: [
'test/**/*.test.js',
'build/typertext.js'
]
],
plugins: [
'karma-jasmine',
"karma-phantomjs-launcher",
'karma-sauce-launcher',
'karma-chrome-launcher'
],
customLaunchers: sauceBrowsers
});
};

View file

@ -6,6 +6,6 @@ module Typertext.Http {
/**
* @class HttpException
*/
export class HttpException extends Typertext.BaseException<HttpResponseStatus> {
export class HttpException extends Typertext.BaseException<HttpResponse> {
}
}

View file

@ -17,7 +17,7 @@ module Typertext.Http {
* @version 0.3.0
* @constructor
*/
constructor() {
constructor() {
}
/**
@ -52,42 +52,57 @@ module Typertext.Http {
*/
public RawRequest(method:HttpMethod, request:HttpUrl, postData:HttpPostData = {}, callback:HttpResponseHandler = (c)=> {
}):void {
var noop = (i:string)=>{
return "";
};
//Create a XHR
var xhr = new XMLHttpRequest();
//And let us know when it does something
xhr.onreadystatechange = ()=> {
//Once the request completes
//If the request is complete
if (xhr.readyState == 4) {
//Prepare a getter for the header
var getHeader = (name:string):string => {
return xhr.getResponseHeader(name);
};
//Check the status
if (xhr.status == 200) {
//And either succeed
callback(new HttpResponse(HttpResponseStatus.success, getHeader, xhr.status, xhr.responseText));
} else if (xhr.status >= 400 && xhr.status < 500) {
//TODO generate a client error callback
throw new HttpException("Error type is unimplemented", -1, HttpResponseStatus.clientError);
//Or fail miserably
throw new HttpException("The server returned an error response state", xhr.status, new HttpResponse(HttpResponseStatus.clientError, getHeader, xhr.status, xhr.responseText));
} else if (xhr.status >= 500 && xhr.status < 600) {
//TODO generate a server error callback
throw new HttpException("Error type is unimplemented", -1, HttpResponseStatus.serverError);
} else {
throw new HttpException("An unknown error has occurred", -2, HttpResponseStatus.unknownError);
//Again
throw new HttpException("The server returned an error response state", xhr.status, new HttpResponse(HttpResponseStatus.serverError, getHeader, xhr.status, xhr.responseText));
}
//And again
throw new HttpException("An unknown error has occurred", -2, new HttpResponse(HttpResponseStatus.unknownError, getHeader, xhr.status, xhr.responseText));
}
};
//Or if it times out
xhr.ontimeout = () => {
callback(new HttpResponse(HttpResponseStatus.timeout));
//And make a big deal of the failing
throw new HttpException("The server took too long to respond to our request", -1, new HttpResponse(HttpResponseStatus.timeout, noop, -1, ""));
};
//Now connect
xhr.open(HttpMethod[method], request.ToString(), true);
//And either send
if (method == HttpMethod.GET) {
//A get request
xhr.send();
return;
}
//Or set the content-type
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
//And send the post-data to the server
xhr.send(HttpUrl.UrlEncodeObject(postData));
}
}

View file

@ -21,7 +21,8 @@
"karma-phantomjs-launcher": "~0.1.2",
"karma": "~0.10.9",
"grunt-karma": "~0.6.2",
"phantomjs": "~1.9.7-1"
"phantomjs": "~1.9.7-1",
"karma-sauce-launcher": "~0.1.8"
},
"license": "MIT",
"scripts": {