Merge pull request #688 from automatisch/revise-custom-errors
Revise custom errors
This commit is contained in:
@@ -3,7 +3,6 @@ import { URLSearchParams } from 'url';
|
|||||||
import scopes from '../common/scopes';
|
import scopes from '../common/scopes';
|
||||||
|
|
||||||
export default async function createAuthData($: IGlobalVariable) {
|
export default async function createAuthData($: IGlobalVariable) {
|
||||||
try {
|
|
||||||
const oauthRedirectUrlField = $.app.auth.fields.find(
|
const oauthRedirectUrlField = $.app.auth.fields.find(
|
||||||
(field: IField) => field.key == 'oAuthRedirectUrl'
|
(field: IField) => field.key == 'oAuthRedirectUrl'
|
||||||
);
|
);
|
||||||
@@ -17,12 +16,7 @@ export default async function createAuthData($: IGlobalVariable) {
|
|||||||
scope: scopes.join(' '),
|
scope: scopes.join(' '),
|
||||||
});
|
});
|
||||||
|
|
||||||
const url = `${
|
const url = `${$.app.apiBaseUrl}/oauth2/authorize?${searchParams.toString()}`;
|
||||||
$.app.apiBaseUrl
|
|
||||||
}/oauth2/authorize?${searchParams.toString()}`;
|
|
||||||
|
|
||||||
await $.auth.set({ url });
|
await $.auth.set({ url });
|
||||||
} catch (error) {
|
|
||||||
throw new Error(`Error occured while verifying credentials: ${error}`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -1,8 +1,7 @@
|
|||||||
import { IJSONObject, IField, IGlobalVariable } from '@automatisch/types';
|
import { IField, IGlobalVariable } from '@automatisch/types';
|
||||||
import { URLSearchParams } from 'url';
|
import { URLSearchParams } from 'url';
|
||||||
|
|
||||||
export default async function createAuthData($: IGlobalVariable) {
|
export default async function createAuthData($: IGlobalVariable) {
|
||||||
try {
|
|
||||||
const oauthRedirectUrlField = $.app.auth.fields.find(
|
const oauthRedirectUrlField = $.app.auth.fields.find(
|
||||||
(field: IField) => field.key == 'oAuthRedirectUrl'
|
(field: IField) => field.key == 'oAuthRedirectUrl'
|
||||||
);
|
);
|
||||||
@@ -19,13 +18,4 @@ export default async function createAuthData($: IGlobalVariable) {
|
|||||||
accessToken: responseData.oauth_token,
|
accessToken: responseData.oauth_token,
|
||||||
accessSecret: responseData.oauth_token_secret,
|
accessSecret: responseData.oauth_token_secret,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
|
||||||
const errorMessages = error.response.data.errors
|
|
||||||
.map((error: IJSONObject) => error.message)
|
|
||||||
.join(' ');
|
|
||||||
|
|
||||||
throw new Error(
|
|
||||||
`Error occured while verifying credentials: ${errorMessages}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -2,7 +2,6 @@ import { IGlobalVariable } from '@automatisch/types';
|
|||||||
import { URLSearchParams } from 'url';
|
import { URLSearchParams } from 'url';
|
||||||
|
|
||||||
const verifyCredentials = async ($: IGlobalVariable) => {
|
const verifyCredentials = async ($: IGlobalVariable) => {
|
||||||
try {
|
|
||||||
const response = await $.http.post(
|
const response = await $.http.post(
|
||||||
`/oauth/access_token?oauth_verifier=${$.auth.data.oauthVerifier}&oauth_token=${$.auth.data.accessToken}`,
|
`/oauth/access_token?oauth_verifier=${$.auth.data.oauthVerifier}&oauth_token=${$.auth.data.accessToken}`,
|
||||||
null
|
null
|
||||||
@@ -18,9 +17,6 @@ const verifyCredentials = async ($: IGlobalVariable) => {
|
|||||||
userId: responseData.user_nsid,
|
userId: responseData.user_nsid,
|
||||||
screenName: responseData.fullname,
|
screenName: responseData.fullname,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
|
||||||
throw new Error(error.response.data);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default verifyCredentials;
|
export default verifyCredentials;
|
||||||
|
@@ -2,7 +2,6 @@ import { IGlobalVariable } from '@automatisch/types';
|
|||||||
import getCurrentUser from '../common/get-current-user';
|
import getCurrentUser from '../common/get-current-user';
|
||||||
|
|
||||||
const verifyCredentials = async ($: IGlobalVariable) => {
|
const verifyCredentials = async ($: IGlobalVariable) => {
|
||||||
try {
|
|
||||||
const response = await $.http.post(
|
const response = await $.http.post(
|
||||||
`${$.app.baseUrl}/login/oauth/access_token`,
|
`${$.app.baseUrl}/login/oauth/access_token`,
|
||||||
{
|
{
|
||||||
@@ -32,9 +31,6 @@ const verifyCredentials = async ($: IGlobalVariable) => {
|
|||||||
userId: currentUser.id,
|
userId: currentUser.id,
|
||||||
screenName: currentUser.login,
|
screenName: currentUser.login,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
|
||||||
throw new Error(error.response.data);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default verifyCredentials;
|
export default verifyCredentials;
|
||||||
|
@@ -2,7 +2,6 @@ import { IField, IGlobalVariable } from '@automatisch/types';
|
|||||||
import qs from 'qs';
|
import qs from 'qs';
|
||||||
|
|
||||||
export default async function createAuthData($: IGlobalVariable) {
|
export default async function createAuthData($: IGlobalVariable) {
|
||||||
try {
|
|
||||||
const oauthRedirectUrlField = $.app.auth.fields.find(
|
const oauthRedirectUrlField = $.app.auth.fields.find(
|
||||||
(field: IField) => field.key == 'oAuthRedirectUrl'
|
(field: IField) => field.key == 'oAuthRedirectUrl'
|
||||||
);
|
);
|
||||||
@@ -16,7 +15,4 @@ export default async function createAuthData($: IGlobalVariable) {
|
|||||||
await $.auth.set({
|
await $.auth.set({
|
||||||
url: `${$.auth.data.oauth2Url}/authorize?${searchParams}`,
|
url: `${$.auth.data.oauth2Url}/authorize?${searchParams}`,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
|
||||||
throw new Error(`Error occured while verifying credentials: ${error}`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -3,7 +3,6 @@ import getCurrentUser from '../common/get-current-user';
|
|||||||
import qs from 'qs';
|
import qs from 'qs';
|
||||||
|
|
||||||
const verifyCredentials = async ($: IGlobalVariable) => {
|
const verifyCredentials = async ($: IGlobalVariable) => {
|
||||||
try {
|
|
||||||
const oauthRedirectUrlField = $.app.auth.fields.find(
|
const oauthRedirectUrlField = $.app.auth.fields.find(
|
||||||
(field) => field.key == 'oAuthRedirectUrl'
|
(field) => field.key == 'oAuthRedirectUrl'
|
||||||
);
|
);
|
||||||
@@ -33,9 +32,6 @@ const verifyCredentials = async ($: IGlobalVariable) => {
|
|||||||
await $.auth.set({
|
await $.auth.set({
|
||||||
screenName: `${currentUser.displayName} - ${data.instance_url}`,
|
screenName: `${currentUser.displayName} - ${data.instance_url}`,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
|
||||||
throw new Error(error.response.data);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default verifyCredentials;
|
export default verifyCredentials;
|
||||||
|
@@ -1,15 +1,11 @@
|
|||||||
import { IGlobalVariable } from '@automatisch/types';
|
import { IGlobalVariable } from '@automatisch/types';
|
||||||
|
|
||||||
const verifyCredentials = async ($: IGlobalVariable) => {
|
const verifyCredentials = async ($: IGlobalVariable) => {
|
||||||
try {
|
|
||||||
await $.http.get('/2010-04-01/Accounts.json?PageSize=1');
|
await $.http.get('/2010-04-01/Accounts.json?PageSize=1');
|
||||||
|
|
||||||
await $.auth.set({
|
await $.auth.set({
|
||||||
screenName: $.auth.data.accountSid,
|
screenName: $.auth.data.accountSid,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
|
||||||
throw new Error(JSON.stringify(error.response.data));
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default verifyCredentials;
|
export default verifyCredentials;
|
||||||
|
@@ -1,8 +1,7 @@
|
|||||||
import { IJSONObject, IField, IGlobalVariable } from '@automatisch/types';
|
import { IField, IGlobalVariable } from '@automatisch/types';
|
||||||
import { URLSearchParams } from 'url';
|
import { URLSearchParams } from 'url';
|
||||||
|
|
||||||
export default async function createAuthData($: IGlobalVariable) {
|
export default async function createAuthData($: IGlobalVariable) {
|
||||||
try {
|
|
||||||
const oauthRedirectUrlField = $.app.auth.fields.find(
|
const oauthRedirectUrlField = $.app.auth.fields.find(
|
||||||
(field: IField) => field.key == 'oAuthRedirectUrl'
|
(field: IField) => field.key == 'oAuthRedirectUrl'
|
||||||
);
|
);
|
||||||
@@ -19,13 +18,4 @@ export default async function createAuthData($: IGlobalVariable) {
|
|||||||
accessToken: responseData.oauth_token,
|
accessToken: responseData.oauth_token,
|
||||||
accessSecret: responseData.oauth_token_secret,
|
accessSecret: responseData.oauth_token_secret,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
|
||||||
const errorMessages = error.response.data.errors
|
|
||||||
.map((error: IJSONObject) => error.message)
|
|
||||||
.join(' ');
|
|
||||||
|
|
||||||
throw new Error(
|
|
||||||
`Error occured while verifying credentials: ${errorMessages}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -2,7 +2,6 @@ import { IGlobalVariable } from '@automatisch/types';
|
|||||||
import { URLSearchParams } from 'url';
|
import { URLSearchParams } from 'url';
|
||||||
|
|
||||||
const verifyCredentials = async ($: IGlobalVariable) => {
|
const verifyCredentials = async ($: IGlobalVariable) => {
|
||||||
try {
|
|
||||||
const response = await $.http.post(
|
const response = await $.http.post(
|
||||||
`/oauth/access_token?oauth_verifier=${$.auth.data.oauthVerifier}&oauth_token=${$.auth.data.accessToken}`,
|
`/oauth/access_token?oauth_verifier=${$.auth.data.oauthVerifier}&oauth_token=${$.auth.data.accessToken}`,
|
||||||
null
|
null
|
||||||
@@ -16,9 +15,6 @@ const verifyCredentials = async ($: IGlobalVariable) => {
|
|||||||
userId: responseData.user_id,
|
userId: responseData.user_id,
|
||||||
screenName: responseData.screen_name,
|
screenName: responseData.screen_name,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
|
||||||
throw new Error(error.response.data);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default verifyCredentials;
|
export default verifyCredentials;
|
||||||
|
@@ -1,17 +1,32 @@
|
|||||||
import { IJSONObject } from '@automatisch/types';
|
import { IJSONObject } from '@automatisch/types';
|
||||||
|
|
||||||
export default class BaseError extends Error {
|
export default class BaseError extends Error {
|
||||||
error = {};
|
details = {};
|
||||||
|
|
||||||
constructor(error?: string | IJSONObject) {
|
constructor(error?: string | IJSONObject) {
|
||||||
super();
|
let computedError: Record<string, unknown>;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.error = JSON.parse(error as string);
|
computedError = JSON.parse(error as string);
|
||||||
} catch {
|
} catch {
|
||||||
this.error = typeof error === 'string' ? { error } : error;
|
computedError = typeof error === 'string' ? { error } : error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let computedMessage: string;
|
||||||
|
try {
|
||||||
|
// challenge to input to see if it is stringified JSON
|
||||||
|
JSON.parse(error as string);
|
||||||
|
computedMessage = error as string;
|
||||||
|
} catch {
|
||||||
|
if (typeof error === 'string') {
|
||||||
|
computedMessage = error;
|
||||||
|
} else {
|
||||||
|
computedMessage = JSON.stringify(error, null, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
super(computedMessage);
|
||||||
|
|
||||||
|
this.details = computedError;
|
||||||
this.name = this.constructor.name;
|
this.name = this.constructor.name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
14
packages/backend/src/errors/create-auth-data.ts
Normal file
14
packages/backend/src/errors/create-auth-data.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import { IJSONObject } from '@automatisch/types';
|
||||||
|
import BaseError from './base';
|
||||||
|
|
||||||
|
export default class CreateAuthDataError extends BaseError {
|
||||||
|
constructor(error: IJSONObject) {
|
||||||
|
const computedError =
|
||||||
|
((error.response as IJSONObject)?.data as IJSONObject) ||
|
||||||
|
(error.message as string);
|
||||||
|
|
||||||
|
super(computedError);
|
||||||
|
|
||||||
|
this.message = `Error occured while creating authorization URL!`;
|
||||||
|
}
|
||||||
|
}
|
@@ -1,3 +0,0 @@
|
|||||||
import BaseError from './base';
|
|
||||||
|
|
||||||
export default class HttpError extends BaseError {}
|
|
12
packages/backend/src/errors/http.ts
Normal file
12
packages/backend/src/errors/http.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import { IJSONObject } from '@automatisch/types';
|
||||||
|
import BaseError from './base';
|
||||||
|
|
||||||
|
export default class HttpError extends BaseError {
|
||||||
|
constructor(error: IJSONObject) {
|
||||||
|
const computedError =
|
||||||
|
((error.response as IJSONObject)?.data as IJSONObject) ||
|
||||||
|
(error.message as string);
|
||||||
|
|
||||||
|
super(computedError);
|
||||||
|
}
|
||||||
|
}
|
@@ -2,6 +2,7 @@ import Context from '../../types/express/context';
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import globalVariable from '../../helpers/global-variable';
|
import globalVariable from '../../helpers/global-variable';
|
||||||
import App from '../../models/app';
|
import App from '../../models/app';
|
||||||
|
import CreateAuthDataError from '../../errors/create-auth-data';
|
||||||
|
|
||||||
type Params = {
|
type Params = {
|
||||||
input: {
|
input: {
|
||||||
@@ -30,12 +31,11 @@ const createAuthData = async (
|
|||||||
const app = await App.findOneByKey(connection.key);
|
const app = await App.findOneByKey(connection.key);
|
||||||
|
|
||||||
const $ = await globalVariable({ connection, app });
|
const $ = await globalVariable({ connection, app });
|
||||||
await authInstance.createAuthData($);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
await authInstance.createAuthData($);
|
||||||
await axios.get(connection.formattedData.url as string);
|
await axios.get(connection.formattedData.url as string);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new Error('Error occured while creating authorization URL!');
|
throw new CreateAuthDataError(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
return connection.formattedData;
|
return connection.formattedData;
|
||||||
|
@@ -23,10 +23,7 @@ const graphQLInstance = graphqlHTTP({
|
|||||||
customFormatErrorFn: (error) => {
|
customFormatErrorFn: (error) => {
|
||||||
logger.error(error.path + ' : ' + error.message + '\n' + error.stack);
|
logger.error(error.path + ' : ' + error.message + '\n' + error.stack);
|
||||||
|
|
||||||
return {
|
return error.originalError;
|
||||||
message: error.message,
|
|
||||||
locations: error.locations,
|
|
||||||
};
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -2,7 +2,7 @@ import axios, { AxiosRequestConfig } from 'axios';
|
|||||||
export { AxiosInstance as IHttpClient } from 'axios';
|
export { AxiosInstance as IHttpClient } from 'axios';
|
||||||
import { IHttpClientParams } from '@automatisch/types';
|
import { IHttpClientParams } from '@automatisch/types';
|
||||||
import { URL } from 'url';
|
import { URL } from 'url';
|
||||||
import HttpError from '../../errors/http-error';
|
import HttpError from '../../errors/http';
|
||||||
|
|
||||||
const removeBaseUrlForAbsoluteUrls = (
|
const removeBaseUrlForAbsoluteUrls = (
|
||||||
requestConfig: AxiosRequestConfig
|
requestConfig: AxiosRequestConfig
|
||||||
@@ -40,7 +40,7 @@ export default function createHttpClient({
|
|||||||
instance.interceptors.response.use(
|
instance.interceptors.response.use(
|
||||||
(response) => response,
|
(response) => response,
|
||||||
(error) => {
|
(error) => {
|
||||||
throw new HttpError(error.response.data);
|
throw new HttpError(error);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
import Flow from '../models/flow';
|
import Flow from '../models/flow';
|
||||||
import globalVariable from '../helpers/global-variable';
|
import globalVariable from '../helpers/global-variable';
|
||||||
import EarlyExitError from '../errors/early-exit';
|
import EarlyExitError from '../errors/early-exit';
|
||||||
import HttpError from '../errors/http-error';
|
import HttpError from '../errors/http';
|
||||||
|
|
||||||
type ProcessFlowOptions = {
|
type ProcessFlowOptions = {
|
||||||
flowId: string;
|
flowId: string;
|
||||||
@@ -27,7 +27,7 @@ export const processFlow = async (options: ProcessFlowOptions) => {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error instanceof EarlyExitError === false) {
|
if (error instanceof EarlyExitError === false) {
|
||||||
if (error instanceof HttpError) {
|
if (error instanceof HttpError) {
|
||||||
$.triggerOutput.error = error.error;
|
$.triggerOutput.error = error.details;
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
$.triggerOutput.error = JSON.parse(error.message);
|
$.triggerOutput.error = JSON.parse(error.message);
|
||||||
|
@@ -6,6 +6,7 @@ import DialogContentText from '@mui/material/DialogContentText';
|
|||||||
import Dialog from '@mui/material/Dialog';
|
import Dialog from '@mui/material/Dialog';
|
||||||
import LoadingButton from '@mui/lab/LoadingButton';
|
import LoadingButton from '@mui/lab/LoadingButton';
|
||||||
import { FieldValues, SubmitHandler } from 'react-hook-form';
|
import { FieldValues, SubmitHandler } from 'react-hook-form';
|
||||||
|
import { IJSONObject } from '@automatisch/types';
|
||||||
|
|
||||||
import useFormatMessage from 'hooks/useFormatMessage';
|
import useFormatMessage from 'hooks/useFormatMessage';
|
||||||
import computeAuthStepVariables from 'helpers/computeAuthStepVariables';
|
import computeAuthStepVariables from 'helpers/computeAuthStepVariables';
|
||||||
@@ -37,7 +38,7 @@ export default function AddAppConnection(
|
|||||||
const { application, connectionId, onClose } = props;
|
const { application, connectionId, onClose } = props;
|
||||||
const { name, authDocUrl, key, auth } = application;
|
const { name, authDocUrl, key, auth } = application;
|
||||||
const formatMessage = useFormatMessage();
|
const formatMessage = useFormatMessage();
|
||||||
const [errorMessage, setErrorMessage] = React.useState<string | null>(null);
|
const [error, setError] = React.useState<IJSONObject | null>(null);
|
||||||
const [inProgress, setInProgress] = React.useState(false);
|
const [inProgress, setInProgress] = React.useState(false);
|
||||||
const hasConnection = Boolean(connectionId);
|
const hasConnection = Boolean(connectionId);
|
||||||
const steps = hasConnection
|
const steps = hasConnection
|
||||||
@@ -59,7 +60,7 @@ export default function AddAppConnection(
|
|||||||
if (!steps) return;
|
if (!steps) return;
|
||||||
|
|
||||||
setInProgress(true);
|
setInProgress(true);
|
||||||
setErrorMessage(null);
|
setError(null);
|
||||||
|
|
||||||
const response: Response = {
|
const response: Response = {
|
||||||
key,
|
key,
|
||||||
@@ -79,9 +80,9 @@ export default function AddAppConnection(
|
|||||||
|
|
||||||
response[step.name] = stepResponse;
|
response[step.name] = stepResponse;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
const error = err as Error;
|
const error = err as IJSONObject;
|
||||||
console.log(error);
|
console.log(error);
|
||||||
setErrorMessage(error.message);
|
setError((error.graphQLErrors as IJSONObject[])?.[0]);
|
||||||
setInProgress(false);
|
setInProgress(false);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -116,9 +117,13 @@ export default function AddAppConnection(
|
|||||||
</Alert>
|
</Alert>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{errorMessage && (
|
{error && (
|
||||||
<Alert severity="error" sx={{ mt: 1, fontWeight: 500 }}>
|
<Alert
|
||||||
{errorMessage}
|
severity="error"
|
||||||
|
sx={{ mt: 1, fontWeight: 500, wordBreak: 'break-all' }}
|
||||||
|
>
|
||||||
|
{error.message}
|
||||||
|
<pre>{JSON.stringify(error.details, null, 2)}</pre>
|
||||||
</Alert>
|
</Alert>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user