Modify error handling
This commit is contained in:
parent
bbfe5166fc
commit
80592f6625
5
build/typertext.d.ts
vendored
5
build/typertext.d.ts
vendored
|
@ -128,8 +128,11 @@ declare module Typertext.Json {
|
|||
}
|
||||
declare module Typertext.Json {
|
||||
class JsonResponse extends GenericResponse<JsonObject> {
|
||||
private parseSuccess;
|
||||
static fromHttpResponse(httpResponse: Http.HttpResponse): JsonResponse;
|
||||
constructor(status: Http.HttpResponseStatus, responseHeaderGetter?: (input: string) => string, httpResponseCode?: number, responseBody?: JsonObject);
|
||||
static fromInvalidHttpResponse(httpResponse: Http.HttpResponse): JsonResponse;
|
||||
constructor(status: Http.HttpResponseStatus, responseHeaderGetter?: (input: string) => string, httpResponseCode?: number, responseBody?: JsonObject, parseSuccess?: boolean);
|
||||
public GetParseStatus(): boolean;
|
||||
}
|
||||
}
|
||||
declare module Typertext.Json {
|
||||
|
|
|
@ -132,17 +132,17 @@ var Typertext;
|
|||
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("The server returned an error response state", xhr.status, new Typertext.Http.HttpResponse(2 /* clientError */, getHeader, xhr.status, xhr.responseText));
|
||||
callback(new Typertext.Http.HttpResponse(2 /* clientError */, getHeader, xhr.status, xhr.responseText));
|
||||
} else if (xhr.status >= 500 && xhr.status < 600) {
|
||||
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));
|
||||
callback(new Typertext.Http.HttpResponse(1 /* serverError */, getHeader, xhr.status, xhr.responseText));
|
||||
} else {
|
||||
throw new Typertext.Http.HttpException("An unknown error has occurred", -2, new Typertext.Http.HttpResponse(4 /* unknownError */, getHeader, xhr.status, xhr.responseText));
|
||||
callback(new Typertext.Http.HttpResponse(4 /* unknownError */, getHeader, xhr.status, xhr.responseText));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
xhr.ontimeout = function () {
|
||||
throw new Typertext.Http.HttpException("The server took too long to respond to our request", -1, new Typertext.Http.HttpResponse(5 /* timeout */, noop, -1, ""));
|
||||
callback(new Typertext.Http.HttpResponse(5 /* timeout */, noop, -1, ""));
|
||||
};
|
||||
|
||||
xhr.open(Typertext.Http.HttpMethod[method], request.ToString(), true);
|
||||
|
@ -315,8 +315,6 @@ var Typertext;
|
|||
(function (Json) {
|
||||
var HttpRequest = Typertext.Http.HttpRequest;
|
||||
|
||||
var HttpResponseStatus = Typertext.Http.HttpResponseStatus;
|
||||
|
||||
var HttpMethod = Typertext.Http.HttpMethod;
|
||||
|
||||
var JsonRequest = (function () {
|
||||
|
@ -336,18 +334,19 @@ var Typertext;
|
|||
JsonRequest.prototype.RawRequest = function (method, request, postData, callback) {
|
||||
var _this = this;
|
||||
if (typeof postData === "undefined") { postData = {}; }
|
||||
if (typeof callback === "undefined") { callback = function (c) {
|
||||
}; }
|
||||
if (typeof callback != "function") {
|
||||
this.request.RawRequest(method, request, postData, function () {
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
this.request.RawRequest(method, request, postData, function (response) {
|
||||
if (response.GetContentType() != _this.jsonType) {
|
||||
callback(new Typertext.Json.JsonResponse(3 /* responseError */));
|
||||
callback(Typertext.Json.JsonResponse.fromInvalidHttpResponse(response));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
callback(Typertext.Json.JsonResponse.fromHttpResponse(response));
|
||||
} catch (e) {
|
||||
throw new Typertext.Json.JsonException("Json parse exception", -1);
|
||||
}
|
||||
callback(Typertext.Json.JsonResponse.fromHttpResponse(response));
|
||||
});
|
||||
};
|
||||
return JsonRequest;
|
||||
|
@ -359,13 +358,29 @@ var Typertext;
|
|||
var Typertext;
|
||||
(function (Typertext) {
|
||||
(function (Json) {
|
||||
var HttpResponseStatus = Typertext.Http.HttpResponseStatus;
|
||||
|
||||
var JsonResponse = (function (_super) {
|
||||
__extends(JsonResponse, _super);
|
||||
function JsonResponse(status, responseHeaderGetter, httpResponseCode, responseBody) {
|
||||
function JsonResponse(status, responseHeaderGetter, httpResponseCode, responseBody, parseSuccess) {
|
||||
_super.call(this, status, responseHeaderGetter, httpResponseCode, responseBody);
|
||||
parseSuccess = !!parseSuccess || false;
|
||||
this.parseSuccess = parseSuccess;
|
||||
}
|
||||
JsonResponse.fromHttpResponse = function (httpResponse) {
|
||||
return new JsonResponse(httpResponse.GetStatus(), httpResponse.GetHeader, httpResponse.GetHttpStatus(), window["JSON"].parse(httpResponse.GetContent()));
|
||||
try {
|
||||
return new JsonResponse(httpResponse.GetStatus(), httpResponse.GetHeader, httpResponse.GetHttpStatus(), window["JSON"].parse(httpResponse.GetContent()), true);
|
||||
} catch (e) {
|
||||
return new JsonResponse(httpResponse.GetStatus(), httpResponse.GetHeader, httpResponse.GetHttpStatus(), null);
|
||||
}
|
||||
};
|
||||
|
||||
JsonResponse.fromInvalidHttpResponse = function (httpResponse) {
|
||||
return new JsonResponse(3 /* responseError */, httpResponse.GetHeader, httpResponse.GetHttpStatus());
|
||||
};
|
||||
|
||||
JsonResponse.prototype.GetParseStatus = function () {
|
||||
return this.parseSuccess;
|
||||
};
|
||||
return JsonResponse;
|
||||
})(Typertext.GenericResponse);
|
||||
|
|
File diff suppressed because one or more lines are too long
2
build/typertext.min.js
vendored
2
build/typertext.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -74,13 +74,13 @@ module Typertext.Http {
|
|||
callback(new HttpResponse(HttpResponseStatus.success, getHeader, xhr.status, xhr.responseText));
|
||||
} else if (xhr.status >= 400 && xhr.status < 500) {
|
||||
//Or fail miserably
|
||||
throw new HttpException("The server returned an error response state", xhr.status, new HttpResponse(HttpResponseStatus.clientError, getHeader, xhr.status, xhr.responseText));
|
||||
callback(new HttpResponse(HttpResponseStatus.clientError, getHeader, xhr.status, xhr.responseText));
|
||||
} else if (xhr.status >= 500 && xhr.status < 600) {
|
||||
//Again
|
||||
throw new HttpException("The server returned an error response state", xhr.status, new HttpResponse(HttpResponseStatus.serverError, getHeader, xhr.status, xhr.responseText));
|
||||
callback(new HttpResponse(HttpResponseStatus.serverError, getHeader, xhr.status, xhr.responseText));
|
||||
} else {
|
||||
//And again
|
||||
throw new HttpException("An unknown error has occurred", -2, new HttpResponse(HttpResponseStatus.unknownError, getHeader, xhr.status, xhr.responseText));
|
||||
callback(new HttpResponse(HttpResponseStatus.unknownError, getHeader, xhr.status, xhr.responseText));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -88,7 +88,7 @@ module Typertext.Http {
|
|||
//Or if it times out
|
||||
xhr.ontimeout = () => {
|
||||
//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, ""));
|
||||
callback(new HttpResponse(HttpResponseStatus.timeout, noop, -1, ""));
|
||||
};
|
||||
|
||||
//Now connect
|
||||
|
|
|
@ -27,8 +27,9 @@ module Typertext.Json {
|
|||
*
|
||||
* @author Kegan Myers <kegan@keganmyers.com>
|
||||
* @version 0.3.0
|
||||
* @constructor
|
||||
*/
|
||||
constructor(jsonContentType:string = "application/json") {
|
||||
constructor(jsonContentType:string = "application/json") {
|
||||
this.request = new HttpRequest();
|
||||
this.jsonType = jsonContentType;
|
||||
}
|
||||
|
@ -62,19 +63,25 @@ module Typertext.Json {
|
|||
* @param {HttpPostData} postData
|
||||
* @param {JsonResponseHandler} callback
|
||||
*/
|
||||
public RawRequest(method:HttpMethod, request:HttpUrl, postData:Typertext.Http.HttpPostData = {}, callback:JsonResponseHandler = (c)=> {
|
||||
}) {
|
||||
public RawRequest(method:HttpMethod, request:HttpUrl, postData:Typertext.Http.HttpPostData = {}, callback?:JsonResponseHandler) {
|
||||
//Ensure we have an executable callback
|
||||
if (typeof callback != "function") {
|
||||
//Make a request and ignore the response, throwing exceptions in async code can be weird
|
||||
this.request.RawRequest(method, request, postData, ()=>{});
|
||||
return;
|
||||
}
|
||||
|
||||
//Make a full request and handle the response
|
||||
this.request.RawRequest(method, request, postData, (response:HttpResponse)=> {
|
||||
//Make sure that we got the Json content type we are expecting
|
||||
if (response.GetContentType() != this.jsonType) {
|
||||
callback(new JsonResponse(HttpResponseStatus.responseError));
|
||||
//If not it is an invalid server response
|
||||
callback(JsonResponse.fromInvalidHttpResponse(response));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
callback(JsonResponse.fromHttpResponse(response));
|
||||
} catch (e) {
|
||||
throw new JsonException("Json parse exception", -1);
|
||||
}
|
||||
//If it is then we can just pass it straight through to the JSON response
|
||||
callback(JsonResponse.fromHttpResponse(response));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,13 @@ module Typertext.Json {
|
|||
|
||||
export class JsonResponse extends Typertext.GenericResponse<JsonObject> {
|
||||
|
||||
/**
|
||||
* @property parseSuccess
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
private parseSuccess:boolean;
|
||||
|
||||
/**
|
||||
* This method handles converting a string into a parsed JSON object
|
||||
*
|
||||
|
@ -15,7 +22,21 @@ module Typertext.Json {
|
|||
* @returns {JsonResponse}
|
||||
*/
|
||||
public static fromHttpResponse(httpResponse:HttpResponse):JsonResponse {
|
||||
return new JsonResponse(httpResponse.GetStatus(), httpResponse.GetHeader, httpResponse.GetHttpStatus(), window["JSON"].parse(httpResponse.GetContent()));
|
||||
try {
|
||||
return new JsonResponse(httpResponse.GetStatus(), httpResponse.GetHeader, httpResponse.GetHttpStatus(), window["JSON"].parse(httpResponse.GetContent()), true);
|
||||
} catch(e) {
|
||||
return new JsonResponse(httpResponse.GetStatus(), httpResponse.GetHeader, httpResponse.GetHttpStatus(), null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method handles creating an unsuccessful JSON response if the content-type is wrong
|
||||
*
|
||||
* @param httpResponse
|
||||
* @returns {JsonResponse}
|
||||
*/
|
||||
public static fromInvalidHttpResponse(httpResponse:HttpResponse):JsonResponse {
|
||||
return new JsonResponse(HttpResponseStatus.responseError, httpResponse.GetHeader, httpResponse.GetHttpStatus());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -26,12 +47,24 @@ module Typertext.Json {
|
|||
* @param {HttpHeaderData} responseHeaders
|
||||
* @param {number} httpResponseCode
|
||||
* @param {JsonObject} responseBody
|
||||
* @param {boolean} parseSuccess
|
||||
*
|
||||
* @author Kegan Myers <kegan@keganmyers.com>
|
||||
* @version 0.3.0
|
||||
*/
|
||||
constructor(status:HttpResponseStatus, responseHeaderGetter?:(input:string)=>string, httpResponseCode?:number, responseBody?:JsonObject) {
|
||||
constructor(status:HttpResponseStatus, responseHeaderGetter?:(input:string)=>string, httpResponseCode?:number, responseBody?:JsonObject, parseSuccess?:boolean) {
|
||||
super(status, responseHeaderGetter, httpResponseCode, responseBody);
|
||||
parseSuccess = !!parseSuccess || false;
|
||||
this.parseSuccess = parseSuccess;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the parsing stage of creating creating the JSON response was successful
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
public GetParseStatus():boolean {
|
||||
return this.parseSuccess;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,41 +4,37 @@ describe("Typertext.Json.JsonResponse", function () {
|
|||
});
|
||||
|
||||
describe("fromHttpResponse", function () {
|
||||
function hf() {
|
||||
return "";
|
||||
}
|
||||
|
||||
it("exists", function () {
|
||||
expect(typeof Typertext.Json.JsonResponse.fromHttpResponse).toBe("function");
|
||||
});
|
||||
|
||||
it("handles an empty json object response", function () {
|
||||
function hf() {
|
||||
return "";
|
||||
}
|
||||
|
||||
var inputBody = "{}",
|
||||
input = new Typertext.Http.HttpResponse(Typertext.Http.HttpResponseStatus.success, hf, 200, inputBody),
|
||||
expectedBody = {},
|
||||
expectedOutput = new Typertext.Json.JsonResponse(Typertext.Http.HttpResponseStatus.success, hf, 200, expectedBody),
|
||||
expectedOutput = new Typertext.Json.JsonResponse(Typertext.Http.HttpResponseStatus.success, hf, 200, expectedBody, true),
|
||||
actualOutput = Typertext.Json.JsonResponse.fromHttpResponse(input);
|
||||
expect(window["JSON"].parse(inputBody)).toEqual(expectedBody);
|
||||
expect(window["JSON"].stringify(actualOutput)).toEqual(window["JSON"].stringify(expectedOutput));
|
||||
});
|
||||
|
||||
it("handles an empty string", function () {
|
||||
function hf() {
|
||||
return "";
|
||||
}
|
||||
|
||||
var inputBody = "",
|
||||
input = new Typertext.Http.HttpResponse(Typertext.Http.HttpResponseStatus.success, hf, 200, inputBody);
|
||||
expect(function () {
|
||||
Typertext.Json.JsonResponse.fromHttpResponse(input);
|
||||
input = new Typertext.Http.HttpResponse(Typertext.Http.HttpResponseStatus.success, hf, 200, inputBody),
|
||||
expectedBody = null,
|
||||
expectedOutput = new Typertext.Json.JsonResponse(Typertext.Http.HttpResponseStatus.success, hf, 200, expectedBody, false),
|
||||
actualOutput = Typertext.Json.JsonResponse.fromHttpResponse(input);
|
||||
expect(function() {
|
||||
window["JSON"].parse(inputBody)
|
||||
}).toThrow();
|
||||
expect(window["JSON"].stringify(actualOutput)).toEqual(window["JSON"].stringify(expectedOutput));
|
||||
});
|
||||
|
||||
it("handles an example server response", function () {
|
||||
function hf() {
|
||||
return "";
|
||||
}
|
||||
|
||||
var inputBody = "{\"access_token\":\"0d95289cb2f54831dc435ce9274b1d1bdf8f5949\",\"expires_in\":86400," +
|
||||
"\"token_type\":\"Bearer\",\"scope\":null," +
|
||||
"\"refresh_token\":\"8a4431470af2edc3fdf747eca5f71451a3ad2d98\"}",
|
||||
|
@ -50,7 +46,7 @@ describe("Typertext.Json.JsonResponse", function () {
|
|||
"scope": null,
|
||||
"refresh_token": "8a4431470af2edc3fdf747eca5f71451a3ad2d98"
|
||||
},
|
||||
expectedOutput = new Typertext.Json.JsonResponse(Typertext.Http.HttpResponseStatus.success, hf, 200, expectedBody),
|
||||
expectedOutput = new Typertext.Json.JsonResponse(Typertext.Http.HttpResponseStatus.success, hf, 200, expectedBody, true),
|
||||
actualOutput = Typertext.Json.JsonResponse.fromHttpResponse(input);
|
||||
expect(window["JSON"].parse(inputBody)).toEqual(expectedBody);
|
||||
expect(window["JSON"].stringify(actualOutput)).toEqual(window["JSON"].stringify(expectedOutput));
|
||||
|
|
Reference in a new issue