Update error handling
This commit is contained in:
parent
a7ce48782c
commit
7a6044525c
35
Gruntfile.js
35
Gruntfile.js
|
@ -2,19 +2,44 @@ module.exports = function (grunt) {
|
||||||
grunt.loadNpmTasks('grunt-karma');
|
grunt.loadNpmTasks('grunt-karma');
|
||||||
grunt.loadNpmTasks('grunt-typescript');
|
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({
|
grunt.initConfig({
|
||||||
karma: {
|
karma: {
|
||||||
phantom: {
|
local: {
|
||||||
configFile: "karma.conf.js",
|
configFile: "karma.conf.js",
|
||||||
singleRun: true,
|
singleRun: true,
|
||||||
browsers: ["PhantomJS"]
|
browsers: ["Chrome", "PhantomJS"]
|
||||||
},
|
},
|
||||||
chrome: {
|
travis: {
|
||||||
configFile: "karma.conf.js",
|
configFile: "karma.conf.js",
|
||||||
singleRun: true,
|
singleRun: true,
|
||||||
browsers: ["Chrome"]
|
browsers: travisBrowsers
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
autoWatch: true,
|
||||||
configFile: "karma.conf.js",
|
configFile: "karma.conf.js",
|
||||||
browsers: ["PhantomJS", "Chrome"]
|
browsers: ["PhantomJS", "Chrome"]
|
||||||
}
|
}
|
||||||
|
@ -34,5 +59,5 @@ module.exports = function (grunt) {
|
||||||
grunt.registerTask('default', ['typescript']);
|
grunt.registerTask('default', ['typescript']);
|
||||||
|
|
||||||
grunt.registerTask('test', ['typescript', 'karma:phantom', 'karma:chrome']);
|
grunt.registerTask('test', ['typescript', 'karma:phantom', 'karma:chrome']);
|
||||||
grunt.registerTask('test:travis', ['typescript', 'karma:phantom']);
|
grunt.registerTask('test:travis', ['typescript', 'karma:travis']);
|
||||||
};
|
};
|
|
@ -12,7 +12,6 @@ Usage
|
||||||
|
|
||||||
Todo
|
Todo
|
||||||
----
|
----
|
||||||
- More robust error handling
|
|
||||||
- IE 8-9 CORS support (XDomain)
|
- IE 8-9 CORS support (XDomain)
|
||||||
- Integrate with Sauce Labs
|
- 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
|
Changelog
|
||||||
---------
|
---------
|
||||||
|
####0.4.0
|
||||||
|
- Modify how exceptions are handled
|
||||||
|
- Steps toward Sauce integration
|
||||||
|
|
||||||
####0.3.3
|
####0.3.3
|
||||||
- Fix Post methods actually calling GET
|
- Fix Post methods actually calling GET
|
||||||
|
|
||||||
|
|
2
build/typertext.d.ts
vendored
2
build/typertext.d.ts
vendored
|
@ -36,7 +36,7 @@ declare module Typertext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
declare module Typertext.Http {
|
declare module Typertext.Http {
|
||||||
class HttpException extends BaseException<HttpResponseStatus> {
|
class HttpException extends BaseException<HttpResponse> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
declare module Typertext.Http {
|
declare module Typertext.Http {
|
||||||
|
|
|
@ -117,26 +117,32 @@ var Typertext;
|
||||||
if (typeof postData === "undefined") { postData = {}; }
|
if (typeof postData === "undefined") { postData = {}; }
|
||||||
if (typeof callback === "undefined") { callback = function (c) {
|
if (typeof callback === "undefined") { callback = function (c) {
|
||||||
}; }
|
}; }
|
||||||
|
var noop = function (i) {
|
||||||
|
return "";
|
||||||
|
};
|
||||||
|
|
||||||
var xhr = new XMLHttpRequest();
|
var xhr = new XMLHttpRequest();
|
||||||
|
|
||||||
xhr.onreadystatechange = function () {
|
xhr.onreadystatechange = function () {
|
||||||
if (xhr.readyState == 4) {
|
if (xhr.readyState == 4) {
|
||||||
var getHeader = function (name) {
|
var getHeader = function (name) {
|
||||||
return xhr.getResponseHeader(name);
|
return xhr.getResponseHeader(name);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (xhr.status == 200) {
|
if (xhr.status == 200) {
|
||||||
callback(new Typertext.Http.HttpResponse(0 /* success */, getHeader, xhr.status, xhr.responseText));
|
callback(new Typertext.Http.HttpResponse(0 /* success */, getHeader, xhr.status, xhr.responseText));
|
||||||
} else if (xhr.status >= 400 && xhr.status < 500) {
|
} 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) {
|
} else if (xhr.status >= 500 && xhr.status < 600) {
|
||||||
throw new Typertext.Http.HttpException("Error type is unimplemented", -1, 1 /* serverError */);
|
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));
|
||||||
} else {
|
|
||||||
throw new Typertext.Http.HttpException("An unknown error has occurred", -2, 4 /* unknownError */);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 () {
|
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);
|
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.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
|
||||||
|
|
||||||
xhr.send(Typertext.Http.HttpUrl.UrlEncodeObject(postData));
|
xhr.send(Typertext.Http.HttpUrl.UrlEncodeObject(postData));
|
||||||
};
|
};
|
||||||
return HttpRequest;
|
return HttpRequest;
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,10 +1,46 @@
|
||||||
module.exports = function (config) {
|
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({
|
config.set({
|
||||||
|
sauceLabs: {
|
||||||
|
startConnect: true,
|
||||||
|
testName: 'TypertextTests',
|
||||||
|
recordScreenshots: false
|
||||||
|
},
|
||||||
basePath: __dirname,
|
basePath: __dirname,
|
||||||
frameworks: ['jasmine'],
|
frameworks: ['jasmine'],
|
||||||
files: [
|
files: [
|
||||||
'test/**/*.test.js',
|
'test/**/*.test.js',
|
||||||
'build/typertext.js'
|
'build/typertext.js'
|
||||||
]
|
],
|
||||||
|
plugins: [
|
||||||
|
'karma-jasmine',
|
||||||
|
"karma-phantomjs-launcher",
|
||||||
|
'karma-sauce-launcher',
|
||||||
|
'karma-chrome-launcher'
|
||||||
|
],
|
||||||
|
customLaunchers: sauceBrowsers
|
||||||
});
|
});
|
||||||
};
|
};
|
|
@ -6,6 +6,6 @@ module Typertext.Http {
|
||||||
/**
|
/**
|
||||||
* @class HttpException
|
* @class HttpException
|
||||||
*/
|
*/
|
||||||
export class HttpException extends Typertext.BaseException<HttpResponseStatus> {
|
export class HttpException extends Typertext.BaseException<HttpResponse> {
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -17,7 +17,7 @@ module Typertext.Http {
|
||||||
* @version 0.3.0
|
* @version 0.3.0
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
constructor() {
|
constructor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -52,42 +52,57 @@ module Typertext.Http {
|
||||||
*/
|
*/
|
||||||
public RawRequest(method:HttpMethod, request:HttpUrl, postData:HttpPostData = {}, callback:HttpResponseHandler = (c)=> {
|
public RawRequest(method:HttpMethod, request:HttpUrl, postData:HttpPostData = {}, callback:HttpResponseHandler = (c)=> {
|
||||||
}):void {
|
}):void {
|
||||||
|
var noop = (i:string)=>{
|
||||||
|
return "";
|
||||||
|
};
|
||||||
|
|
||||||
|
//Create a XHR
|
||||||
var xhr = new XMLHttpRequest();
|
var xhr = new XMLHttpRequest();
|
||||||
|
|
||||||
|
//And let us know when it does something
|
||||||
xhr.onreadystatechange = ()=> {
|
xhr.onreadystatechange = ()=> {
|
||||||
//Once the request completes
|
//If the request is complete
|
||||||
if (xhr.readyState == 4) {
|
if (xhr.readyState == 4) {
|
||||||
|
//Prepare a getter for the header
|
||||||
var getHeader = (name:string):string => {
|
var getHeader = (name:string):string => {
|
||||||
return xhr.getResponseHeader(name);
|
return xhr.getResponseHeader(name);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//Check the status
|
||||||
if (xhr.status == 200) {
|
if (xhr.status == 200) {
|
||||||
|
//And either succeed
|
||||||
callback(new HttpResponse(HttpResponseStatus.success, getHeader, xhr.status, xhr.responseText));
|
callback(new HttpResponse(HttpResponseStatus.success, getHeader, xhr.status, xhr.responseText));
|
||||||
|
|
||||||
} else if (xhr.status >= 400 && xhr.status < 500) {
|
} else if (xhr.status >= 400 && xhr.status < 500) {
|
||||||
//TODO generate a client error callback
|
//Or fail miserably
|
||||||
throw new HttpException("Error type is unimplemented", -1, HttpResponseStatus.clientError);
|
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) {
|
} else if (xhr.status >= 500 && xhr.status < 600) {
|
||||||
//TODO generate a server error callback
|
//Again
|
||||||
throw new HttpException("Error type is unimplemented", -1, HttpResponseStatus.serverError);
|
throw new HttpException("The server returned an error response state", xhr.status, new HttpResponse(HttpResponseStatus.serverError, getHeader, xhr.status, xhr.responseText));
|
||||||
|
|
||||||
} else {
|
|
||||||
throw new HttpException("An unknown error has occurred", -2, HttpResponseStatus.unknownError);
|
|
||||||
}
|
}
|
||||||
|
//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 = () => {
|
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);
|
xhr.open(HttpMethod[method], request.ToString(), true);
|
||||||
|
|
||||||
|
//And either send
|
||||||
if (method == HttpMethod.GET) {
|
if (method == HttpMethod.GET) {
|
||||||
|
//A get request
|
||||||
xhr.send();
|
xhr.send();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Or set the content-type
|
||||||
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
|
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
|
||||||
|
//And send the post-data to the server
|
||||||
xhr.send(HttpUrl.UrlEncodeObject(postData));
|
xhr.send(HttpUrl.UrlEncodeObject(postData));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,8 @@
|
||||||
"karma-phantomjs-launcher": "~0.1.2",
|
"karma-phantomjs-launcher": "~0.1.2",
|
||||||
"karma": "~0.10.9",
|
"karma": "~0.10.9",
|
||||||
"grunt-karma": "~0.6.2",
|
"grunt-karma": "~0.6.2",
|
||||||
"phantomjs": "~1.9.7-1"
|
"phantomjs": "~1.9.7-1",
|
||||||
|
"karma-sauce-launcher": "~0.1.8"
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
Reference in a new issue