Skip to content

Commit

Permalink
Merge pull request #1 from vultuk/error-handling
Browse files Browse the repository at this point in the history
Error handling
  • Loading branch information
vultuk committed Aug 6, 2017
2 parents f77b1d8 + 6481687 commit d4fc175
Show file tree
Hide file tree
Showing 16 changed files with 253 additions and 3 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "node-tide",
"version": "0.2.3",
"version": "0.3.0",
"description": "A Node module to assist with connections to the Tide business banking API",
"author": "Simon Skinner <simon@sisk-ltd.co.uk>",
"repository": {
Expand Down
20 changes: 20 additions & 0 deletions src/errors/badRequest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import * as Interfaces from "../interfaces";

export class BadRequestError extends Error implements Interfaces.ErrorMessage {

/**
* Holds a basic message about this error
*/
message: string = "Invalid Input";

/**
* Holds the HTTP error code associated with the error
*/
httpErrorCode: number = 400;

/**
* Holds a more desciptive message about the error
*/
description: string = "An input was expected but it was not there. Therefore we could not perform the API request.";

}
20 changes: 20 additions & 0 deletions src/errors/forbidden.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import * as Interfaces from "../interfaces";

export class ForbiddenError extends Error implements Interfaces.ErrorMessage {

/**
* Holds a basic message about this error
*/
message: string = "Forbidden";

/**
* Holds the HTTP error code associated with the error
*/
httpErrorCode: number = 403;

/**
* Holds a more desciptive message about the error
*/
description: string = "You do not have the required permissions to access the requested resource.";

}
9 changes: 9 additions & 0 deletions src/errors/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export { BadRequestError } from "./badRequest";
export { ForbiddenError } from "./forbidden";
export { InternalServerError } from "./internalServerError";
export { NotAcceptableError } from "./notAcceptable";
export { NotAllowedError } from "./notAllowed";
export { NotFoundError } from "./notFound";
export { TooManyRequestsError } from "./tooManyRequests";
export { UnauthorisedError } from "./unauthorised";
export { UnavailableError } from "./unavailable";
20 changes: 20 additions & 0 deletions src/errors/internalServerError.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import * as Interfaces from "../interfaces";

export class InternalServerError extends Error implements Interfaces.ErrorMessage {

/**
* Holds a basic message about this error
*/
message: string = "Internal Server Error";

/**
* Holds the HTTP error code associated with the error
*/
httpErrorCode: number = 500;

/**
* Holds a more desciptive message about the error
*/
description: string = "An error has occurred in either Tide's service or the Node-Tide module. Please inspect this error further for full details.";

}
20 changes: 20 additions & 0 deletions src/errors/notAcceptable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import * as Interfaces from "../interfaces";

export class NotAcceptableError extends Error implements Interfaces.ErrorMessage {

/**
* Holds a basic message about this error
*/
message: string = "Not Acceptable";

/**
* Holds the HTTP error code associated with the error
*/
httpErrorCode: number = 406;

/**
* Holds a more desciptive message about the error
*/
description: string = "You requested a format that isn’t JSON.";

}
20 changes: 20 additions & 0 deletions src/errors/notAllowed.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import * as Interfaces from "../interfaces";

export class NotAllowedError extends Error implements Interfaces.ErrorMessage {

/**
* Holds a basic message about this error
*/
message: string = "Not Allowed";

/**
* Holds the HTTP error code associated with the error
*/
httpErrorCode: number = 405;

/**
* Holds a more desciptive message about the error
*/
description: string = "You tried to access a resource with an invalid method.";

}
20 changes: 20 additions & 0 deletions src/errors/notFound.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import * as Interfaces from "../interfaces";

export class NotFoundError extends Error implements Interfaces.ErrorMessage {

/**
* Holds a basic message about this error
*/
message: string = "Not Found";

/**
* Holds the HTTP error code associated with the error
*/
httpErrorCode: number = 404;

/**
* Holds a more desciptive message about the error
*/
description: string = "The requested resource was not found.";

}
20 changes: 20 additions & 0 deletions src/errors/tooManyRequests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import * as Interfaces from "../interfaces";

export class TooManyRequestsError extends Error implements Interfaces.ErrorMessage {

/**
* Holds a basic message about this error
*/
message: string = "Too Many Requests";

/**
* Holds the HTTP error code associated with the error
*/
httpErrorCode: number = 429;

/**
* Holds a more desciptive message about the error
*/
description: string = "There have been too many requests to this resource this hour, please ensure you stay within appropriate rate limiting.";

}
20 changes: 20 additions & 0 deletions src/errors/unauthorised.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import * as Interfaces from "../interfaces";

export class UnauthorisedError extends Error implements Interfaces.ErrorMessage {

/**
* Holds a basic message about this error
*/
message: string = "Unauthorised";

/**
* Holds the HTTP error code associated with the error
*/
httpErrorCode: number = 401;

/**
* Holds a more desciptive message about the error
*/
description: string = "It has not been possible to access the Tide API as no valid access token was provided.";

}
20 changes: 20 additions & 0 deletions src/errors/unavailable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import * as Interfaces from "../interfaces";

export class UnavailableError extends Error implements Interfaces.ErrorMessage {

/**
* Holds a basic message about this error
*/
message: string = "Unavailable";

/**
* Holds the HTTP error code associated with the error
*/
httpErrorCode: number = 503;

/**
* Holds a more desciptive message about the error
*/
description: string = "Tide's API service is currently undergoing maintainance. Please try again later.";

}
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from "./services";
export * from "./interfaces";
export * from "./errors";

import * as Services from "./services";

Expand Down
18 changes: 18 additions & 0 deletions src/interfaces/errorMessage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export interface ErrorMessage {

/**
* Holds a basic message about this error
*/
message: string;

/**
* Holds the HTTP error code associated with the error
*/
httpErrorCode: number;

/**
* Holds a more desciptive message about the error
*/
description: string;

}
1 change: 1 addition & 0 deletions src/interfaces/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ export { Credentials } from "./credentials";
export { Service } from "./service";
export { Factory } from "./factory";
export { RequiresService } from "./requiresService";
export { ErrorMessage } from "./errorMessage";
2 changes: 1 addition & 1 deletion src/services/accounts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export class Accounts extends RequiresService {
*/
public all(companyId: number): Promise<Entities.Account[]> {
return this.service.getRequest(`/external/companies/${companyId}/accounts`, {})
.then(response => (new Factories.Account).items(response))
.then(response => (new Factories.Account).items(response));
}

}
43 changes: 42 additions & 1 deletion src/services/tideService.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import * as Errors from "../errors";
import * as Interfaces from "../interfaces";
import * as request from "request-promise-native";

Expand Down Expand Up @@ -65,7 +66,47 @@ export class TideService implements Interfaces.Service {
},
body: data,
json: true
}));
}))
.catch(err => {
throw this.returnError(err.statusCode, err);
});
}

/**
* Find the appropriate error required to be thrown for this hrrp request
* @param {number} code The error code thrown by the API
* @param {Error} err The original Error
* @return {Interfaces.ErrorMessage} The node-tide error message
*/
private returnError(code: number, err: Error): Interfaces.ErrorMessage {
switch(code) {
case 400:
return new Errors.BadRequestError();
case 401:
return new Errors.UnauthorisedError();
case 403:
return new Errors.ForbiddenError();
case 404:
return new Errors.NotFoundError();
case 405:
return new Errors.NotAllowedError();
case 406:
return new Errors.NotAcceptableError();
case 429:
return new Errors.TooManyRequestsError();
case 500:
return new Errors.InternalServerError();
case 503:
return new Errors.UnavailableError();
default:
let newError: Interfaces.ErrorMessage = new Errors.InternalServerError();

newError.message = err.message;
newError.description = err.message;
newError.httpErrorCode = 500;

return newError;
}
}

}

0 comments on commit d4fc175

Please sign in to comment.