| 138 | } |
| 139 | |
| 140 | const batch = transactionRetries => { |
| 141 | let initialPromise = Promise.resolve(); |
| 142 | if (req.body?.transaction === true) { |
| 143 | initialPromise = req.config.database.createTransactionalSession(); |
| 144 | } |
| 145 | |
| 146 | return initialPromise.then(() => { |
| 147 | const promises = req.body?.requests.map(restRequest => { |
| 148 | const routablePath = makeRoutablePath(restRequest.path); |
| 149 | |
| 150 | // Construct a request that we can send to a handler |
| 151 | const request = { |
| 152 | body: restRequest.body, |
| 153 | config: req.config, |
| 154 | auth: req.auth, |
| 155 | info: req.info, |
| 156 | }; |
| 157 | |
| 158 | return router.tryRouteRequest(restRequest.method, routablePath, request).then( |
| 159 | response => { |
| 160 | return { success: response.response }; |
| 161 | }, |
| 162 | error => { |
| 163 | return { error: { code: error.code, error: error.message } }; |
| 164 | } |
| 165 | ); |
| 166 | }); |
| 167 | |
| 168 | return Promise.all(promises) |
| 169 | .then(results => { |
| 170 | if (req.body?.transaction === true) { |
| 171 | if (results.find(result => typeof result.error === 'object')) { |
| 172 | return req.config.database.abortTransactionalSession().then(() => { |
| 173 | return Promise.reject({ response: results }); |
| 174 | }); |
| 175 | } else { |
| 176 | return req.config.database.commitTransactionalSession().then(() => { |
| 177 | return { response: results }; |
| 178 | }); |
| 179 | } |
| 180 | } else { |
| 181 | return { response: results }; |
| 182 | } |
| 183 | }) |
| 184 | .catch(error => { |
| 185 | if ( |
| 186 | error && |
| 187 | error.response && |
| 188 | error.response.find( |
| 189 | errorItem => typeof errorItem.error === 'object' && errorItem.error.code === 251 |
| 190 | ) && |
| 191 | transactionRetries > 0 |
| 192 | ) { |
| 193 | return batch(transactionRetries - 1); |
| 194 | } |
| 195 | throw error; |
| 196 | }); |
| 197 | }); |
no test coverage detected