Bug 35199: (bug 34448 follow-up) Fix error handling in http-client.js
[koha.git] / koha-tmpl / intranet-tmpl / prog / js / vue / fetch / http-client.js
1 import { setError, submitting, submitted } from "../messages";
2
3 class HttpClient {
4     constructor(options = {}) {
5         this._baseURL = options.baseURL || "";
6         this._headers = options.headers || {
7             "Content-Type": "application/json;charset=utf-8",
8         };
9     }
10
11     async _fetchJSON(
12         endpoint,
13         headers = {},
14         options = {},
15         return_response = false,
16         mark_submitting = false
17     ) {
18         let res, error;
19         if (mark_submitting) submitting();
20         await fetch(this._baseURL + endpoint, {
21             ...options,
22             headers: { ...this._headers, ...headers },
23         })
24             .then(response => {
25                 if (!response.ok) {
26                     return response.text().then(text => {
27                         let message;
28                         if (text) {
29                             let json = JSON.parse(text);
30                             message =
31                                 json.error ||
32                                 json.errors.map(e => e.message).join("\n") ||
33                                 json;
34                         } else {
35                             message = response.statusText;
36                         }
37                         throw new Error(message);
38                     });
39                 }
40                 return return_response ? response : response.json();
41             })
42             .then(result => {
43                 res = result;
44             })
45             .catch(err => {
46                 error = err;
47                 setError(err);
48             })
49             .then(() => {
50                 if (mark_submitting) submitted();
51             });
52
53         if (error) throw Error(error);
54
55         return res;
56     }
57
58     get(params = {}) {
59         return this._fetchJSON(params.endpoint, params.headers, {
60             ...params.options,
61             method: "GET",
62         });
63     }
64
65     getAll(params = {}) {
66         let url =
67             params.endpoint +
68             "?" +
69             new URLSearchParams({
70                 _per_page: -1,
71                 ...(params.params && params.params),
72                 ...(params.query && { q: JSON.stringify(params.query) }),
73             });
74         return this._fetchJSON(url, params.headers, {
75             ...params.options,
76             method: "GET",
77         });
78     }
79
80     post(params = {}) {
81         const body = params.body
82             ? typeof params.body === "string"
83                 ? params.body
84                 : JSON.stringify(params.body)
85             : undefined;
86         return this._fetchJSON(
87             params.endpoint,
88             params.headers,
89             {
90                 ...params.options,
91                 body,
92                 method: "POST",
93             },
94             false,
95             true
96         );
97     }
98
99     put(params = {}) {
100         const body = params.body
101             ? typeof params.body === "string"
102                 ? params.body
103                 : JSON.stringify(params.body)
104             : undefined;
105         return this._fetchJSON(
106             params.endpoint,
107             params.headers,
108             {
109                 ...params.options,
110                 body,
111                 method: "PUT",
112             },
113             false,
114             true
115         );
116     }
117
118     delete(params = {}) {
119         return this._fetchJSON(
120             params.endpoint,
121             params.headers,
122             {
123                 parseResponse: false,
124                 ...params.options,
125                 method: "DELETE",
126             },
127             true,
128             true
129         );
130     }
131
132     count(params = {}) {
133         let res;
134         return this._fetchJSON(params.endpoint, params.headers, {}, 1).then(
135             response => {
136                 if (response) {
137                     return response.headers.get("X-Total-Count");
138                 }
139             },
140             error => {}
141         );
142     }
143
144     patch(params = {}) {
145         const body = params.body
146             ? typeof params.body === "string"
147                 ? params.body
148                 : JSON.stringify(params.body)
149             : undefined;
150         return this._fetchJSON(params.endpoint, params.headers, {
151             ...params.options,
152             body,
153             method: "PATCH",
154         });
155     }
156 }
157
158 export default HttpClient;