1
0
mirror of https://github.com/ascribe/onion.git synced 2024-06-28 08:37:59 +02:00
onion/js/utils/requests.js

173 lines
5.8 KiB
JavaScript
Raw Normal View History

'use strict';
2015-07-24 13:44:28 +02:00
import Q from 'q';
2015-07-17 15:41:09 +02:00
import AppConstants from '../constants/application_constants';
2015-06-01 14:22:04 +02:00
import { getCookie } from '../utils/fetch_api_utils';
import { omitFromObject } from '../utils/general_utils';
import { argsToQueryParams } from '../utils/url_utils';
2015-06-01 14:22:04 +02:00
class Requests {
unpackResponse(url) {
return (response) => {
if (response == null) {
2016-03-10 12:16:30 +01:00
throw new Error(`For: ${url} - Server did not respond to the request. (Not even displayed a 500)`);
}
2015-06-01 14:22:04 +02:00
if (response.status >= 500) {
2016-03-10 12:16:30 +01:00
let err = new Error(`${response.status} - ${response.statusText} - on URL: ${response.url}`);
return response
.text()
.then((resText) => {
const resJson = JSON.parse(resText);
err = new Error(resJson.errors.pop());
2016-03-10 12:16:30 +01:00
// ES6 promises don't have a .finally() clause so we fake that here by
// forcing the .catch() clause to run
return Promise.reject();
})
2016-03-10 12:16:30 +01:00
// If parsing the resText throws, just rethrow the original error we created
.catch(() => { throw err; });
}
return Q.Promise((resolve, reject) => {
response.text()
.then((responseText) => {
// If the responses' body does not contain any data,
// fetch will resolve responseText to the string 'None'.
// If this is the case, we can not try to parse it as JSON.
if (responseText && responseText !== 'None') {
const body = JSON.parse(responseText);
2016-03-10 12:16:30 +01:00
if (body && body.errors) {
const error = new Error('Form Error');
error.json = body;
reject(error);
2016-03-10 12:16:30 +01:00
} else if (body && body.detail) {
reject(new Error(body.detail));
2016-03-10 12:16:30 +01:00
} else if (body && 'success' in body && !body.success) {
const error = new Error('Client Request Error');
error.json = {
2016-03-10 12:16:30 +01:00
body: body,
status: response.status,
statusText: response.statusText,
type: response.type,
url: response.url
};
reject(error);
} else {
resolve(body);
}
2016-03-10 12:16:30 +01:00
} else if (response.status >= 400) {
reject(new Error(`${response.status} - ${response.statusText} - on URL: ${response.url}`));
2015-07-17 16:44:24 +02:00
} else {
2016-03-10 12:16:30 +01:00
resolve({});
2015-07-17 16:44:24 +02:00
}
}).catch(reject);
2015-07-17 16:44:24 +02:00
});
2016-02-17 11:38:01 +01:00
};
2015-06-01 14:22:04 +02:00
}
getUrl(url) {
// Handle case, that the url string is not defined at all
if (!url) {
throw new Error('Url was not defined and could therefore not be mapped.');
}
2015-06-01 14:22:04 +02:00
let name = url;
if (!url.match(/^http/)) {
url = this.urlMap[url];
if (!url) {
2015-07-17 15:41:09 +02:00
throw new Error(`Cannot find a mapping for "${name}"`);
2015-06-01 14:22:04 +02:00
}
}
return url;
}
2015-06-01 16:45:09 +02:00
prepareUrl(url, params, attachParamsToQuery) {
let newUrl;
2015-06-01 14:22:04 +02:00
let re = /\${(\w+)}/g;
2015-06-02 16:47:25 +02:00
// catch errors and throw them to react
try {
newUrl = this.getUrl(url);
} catch(err) {
throw err;
}
2015-08-06 10:09:25 +02:00
2015-06-01 14:22:04 +02:00
newUrl = newUrl.replace(re, (match, key) => {
let val = params[key];
2015-06-01 14:22:04 +02:00
if (!val) {
throw new Error(`Cannot find param ${key}`);
}
delete params[key];
return val;
});
2015-06-01 16:45:09 +02:00
if (attachParamsToQuery && params && Object.keys(params).length > 0) {
newUrl += argsToQueryParams(params);
2015-06-01 14:22:04 +02:00
}
return newUrl;
}
request(verb, url, options = {}) {
let merged = Object.assign({}, this.httpOptions, options);
2015-07-16 18:17:45 +02:00
let csrftoken = getCookie(AppConstants.csrftoken);
2015-06-16 19:28:21 +02:00
if (csrftoken) {
merged.headers['X-CSRFToken'] = csrftoken;
}
merged.method = verb;
return fetch(url, merged)
.then(this.unpackResponse(url));
2015-06-01 14:22:04 +02:00
}
2015-06-01 16:45:09 +02:00
get(url, params) {
if (url === undefined) {
2015-06-20 16:43:18 +02:00
throw new Error('Url undefined');
}
let paramsCopy = Object.assign({}, params);
2015-06-09 17:24:06 +02:00
let newUrl = this.prepareUrl(url, paramsCopy, true);
2015-06-02 14:33:00 +02:00
return this.request('get', newUrl);
2015-06-01 14:22:04 +02:00
}
2015-06-10 15:49:46 +02:00
delete(url, params) {
let paramsCopy = Object.assign({}, params);
2015-06-10 15:49:46 +02:00
let newUrl = this.prepareUrl(url, paramsCopy, true);
return this.request('delete', newUrl);
}
_putOrPost(url, paramsAndBody, method) {
let params = omitFromObject(paramsAndBody, ['body']);
2015-09-03 15:53:02 +02:00
let newUrl = this.prepareUrl(url, params);
let body = paramsAndBody && paramsAndBody.body ? JSON.stringify(paramsAndBody.body)
: null;
2015-09-03 15:53:02 +02:00
return this.request(method, newUrl, { body });
}
post(url, params) {
2015-09-07 16:36:31 +02:00
return this._putOrPost(url, params, 'post');
2015-09-03 15:53:02 +02:00
}
put(url, params) {
2015-09-07 16:36:31 +02:00
return this._putOrPost(url, params, 'put');
2015-06-01 14:22:04 +02:00
}
patch(url, params) {
return this._putOrPost(url, params, 'patch');
}
2015-06-01 14:22:04 +02:00
defaults(options) {
this.httpOptions = options.http || {};
this.urlMap = options.urlMap || {};
}
}
let requests = new Requests();
2015-06-01 14:22:04 +02:00
export default requests;