Skip to content

Commit

Permalink
(Exceptions) clean up exceptions
Browse files Browse the repository at this point in the history
  • Loading branch information
dilame committed Apr 10, 2019
1 parent 668d0a0 commit e9155b1
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 62 deletions.
28 changes: 20 additions & 8 deletions src/core/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,14 @@ import { IgApiClient } from '../client';
import { inRange, random } from 'lodash';
import * as request from 'request-promise';
import { Options, Response } from 'request';
import { ActionSpamError, AuthenticationError, CheckpointError, RequestError, SentryBlockError } from '../exceptions';
import {
ActionSpamError,
AuthenticationError,
CheckpointError,
PrivateUserError,
RequestError,
SentryBlockError,
} from '../exceptions';
import { plainToClass } from 'class-transformer';
import { CheckpointResponse } from '../responses';
import hmac = require('crypto-js/hmac-sha256');
Expand Down Expand Up @@ -33,14 +40,19 @@ export class Request {
private static handleError(response: Response) {
const json = response.body;
if (json.spam) {
return new ActionSpamError(json);
return new ActionSpamError(response);
}
if (json.message === 'challenge_required') {
const checkpointResponse = plainToClass(CheckpointResponse, json as CheckpointResponse);
return new CheckpointError(checkpointResponse);
}
if (json.message === 'login_required') {
return new AuthenticationError('Login required to process this request');
if (typeof json.message === 'string') {
if (json.message === 'challenge_required') {
const checkpointResponse = plainToClass(CheckpointResponse, json as CheckpointResponse);
return new CheckpointError(checkpointResponse);
}
if (json.message === 'login_required') {
return new AuthenticationError(response);
}
if (json.message.toLowerCase() === 'not authorized to view user') {
return new PrivateUserError(response);
}
}
if (json.error_type === 'sentry_block') {
return new SentryBlockError(json);
Expand Down
67 changes: 13 additions & 54 deletions src/exceptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,75 +3,38 @@ import { CustomError } from 'ts-custom-error';
import * as routes from './core/routes';
import { CheckpointResponse } from './responses';
import { Response } from 'request';
import { LoginRequiredResponse, SpamResponse } from './responses';

// Basic error
export class APIError extends CustomError {
constructor(message = 'Instagram API error was made.') {
super(message);
}

serialize() {
return {
error: this.constructor.name,
errorMessage: this.message,
};
}
}

export class RequestError extends APIError {
constructor(public response: Response) {
export class RequestError<TBody extends { [x: string]: any } = any> extends APIError {
constructor(public response: Pick<Response, Exclude<keyof Response, 'body'>> & { body: TBody }) {
super(
`${response.request.method} ${response.request.uri.path} - ${response.statusCode} ${
response.statusMessage
} ${response.body.message || ''}`,
`${response.body.message || ''}; ${response.request.method} ${response.request.uri.path} - ${
response.statusCode
} ${response.statusMessage}`,
);
}
}

export class AuthenticationError extends APIError {
constructor(message = 'Not possible to authenticate') {
super(message);
}
}
export class AuthenticationError extends RequestError<LoginRequiredResponse> {}

export class ParseError extends APIError {
constructor(public body: string) {
super('Not possible to parse API response');
}
}

export class ActionSpamError extends APIError {
constructor(public json) {
super('This action was disabled due to block from instagram!');
this.json = json;
}

serialize() {
return _.extend(APIError.prototype.serialize.call(this), {
errorData: {
blockTime: this.getBlockTime(),
message: this.getFeedbackMessage(),
},
});
}

getBlockTime() {
if (_.isObject(this.json) && _.isString(this.json.feedback_message)) {
const hours = this.json.feedback_message.match(/(\d+)(\s)*hour(s)/);
if (!hours || !_.isArray(hours)) return 0;
const blockTime = parseInt(hours[1]) * 60 * 60 * 1000;
return blockTime + 1000 * 60 * 5;
}
return 0;
}

getFeedbackMessage() {
let message = 'No feedback message';
if (_.isString(this.json.feedback_message)) {
const title = _.isString(this.json.feedback_title) ? this.json.feedback_title + ': ' : '';
message = title + this.json.feedback_message;
}
return message;
export class ActionSpamError extends RequestError<SpamResponse> {
get expirationDate(): string | null {
const date = this.response.body.feedback_message.match(/(\d{4}-\d{2}-\d{2})/);
if (date === null) return null;
return date[0];
}
}

Expand Down Expand Up @@ -110,11 +73,7 @@ export class NotFoundError extends APIError {
}
}

export class PrivateUserError extends APIError {
constructor(message = 'User is private and you are not authorized to view his content!') {
super(message);
}
}
export class PrivateUserError extends RequestError {}

export class TooManyFollowsError extends APIError {
constructor() {
Expand Down
2 changes: 2 additions & 0 deletions src/responses/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ export * from './account.repository.login.response';
export * from './user.repository.info.response';
export * from './user.repository.search.response';
export * from './user.feed.response';
export * from './spam.response';
export * from './login-required.response';
5 changes: 5 additions & 0 deletions src/responses/login-required.response.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface LoginRequiredResponse {
message: 'login_required';
logout_reason: number;
status: 'fail';
}
11 changes: 11 additions & 0 deletions src/responses/spam.response.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export interface SpamResponse {
message: 'feedback_required';
spam: true;
feedback_title: string;
feedback_message: string;
feedback_url: string;
feedback_appeal_label: string;
feedback_ignore_label: string;
feedback_action: string;
status: 'fail';
}

0 comments on commit e9155b1

Please sign in to comment.