diff --git a/api/src/paths/batch/{id}/execute.ts b/api/src/paths/batch/{id}/execute.ts
index 52aa56407..d5db361ea 100644
--- a/api/src/paths/batch/{id}/execute.ts
+++ b/api/src/paths/batch/{id}/execute.ts
@@ -149,7 +149,7 @@ function execBatch(): RequestHandler {
} catch (error) {
defaultLog.error(error);
return res.status(400).json({
- message: 'Batch update exec failed',
+ message: 'Batch update exec failed, error: ' + error.message,
request: req.body,
count: 1,
namespace: 'batch',
diff --git a/api/src/utils/batch/execution.ts b/api/src/utils/batch/execution.ts
index f0f4d27c3..03bed8201 100644
--- a/api/src/utils/batch/execution.ts
+++ b/api/src/utils/batch/execution.ts
@@ -101,81 +101,91 @@ export const BatchExecutionService = {
if (statusQueryResult.rowCount !== 1) {
throw new Error('Batch not in executable status');
}
- for (const [index, row] of validatedBatchData.rows.entries()) {
- let errorRow = false;
- if (row.rowValidationResult.find((vr) => !vr.valid)) {
- errorRow = true;
- } else {
- Object.values(row.data).forEach((propertyValue: any) => {
- if (
- (propertyValue.validationMessages.length > 0 &&
- propertyValue.validationMessages.find((vm) => vm.severity === 'error')) ||
- row.RowValidationResult
- ) {
- errorRow = true;
- }
- });
- }
- if (errorRow && errorRowsBehaviour === 'Skip') continue;
-
- const { id: activityId, shortId, payload, geog } = _mapToDBObject(
- row,
- desiredFinalStatus,
- template.type,
- template.subtype,
- userInfo
- );
-
- let guid = null;
- if (userInfo?.idir_userid !== null) {
- guid = userInfo?.idir_userid.toLowerCase() + '@idir';
- } else if (userInfo?.bceid_userid !== null) {
- guid = userInfo?.bceid_userid.toLowerCase() + '@bceid-business';
- }
- const qc = {
- text: `INSERT INTO activity_incoming_data (activity_id, short_id, activity_payload, batch_id, activity_type,
+
+ await dbConnection.query('BEGIN;');
+
+ try {
+ for (const [index, row] of validatedBatchData.rows.entries()) {
+ let errorRow = false;
+ if (row.rowValidationResult.find((vr) => !vr.valid)) {
+ errorRow = true;
+ } else {
+ Object.values(row.data).forEach((propertyValue: any) => {
+ if (
+ (propertyValue.validationMessages.length > 0 &&
+ propertyValue.validationMessages.find((vm) => vm.severity === 'error')) ||
+ row.RowValidationResult
+ ) {
+ errorRow = true;
+ }
+ });
+ }
+ if (errorRow && errorRowsBehaviour === 'Skip') continue;
+
+ const { id: activityId, shortId, payload, geog } = _mapToDBObject(
+ row,
+ desiredFinalStatus,
+ template.type,
+ template.subtype,
+ userInfo
+ );
+
+ let guid = null;
+ if (userInfo?.idir_userid !== null) {
+ guid = userInfo?.idir_userid.toLowerCase() + '@idir';
+ } else if (userInfo?.bceid_userid !== null) {
+ guid = userInfo?.bceid_userid.toLowerCase() + '@bceid-business';
+ }
+ const qc = {
+ text: `INSERT INTO activity_incoming_data (activity_id, short_id, activity_payload, batch_id, activity_type,
activity_subtype, form_status, created_by, updated_by,
created_by_with_guid, updated_by_with_guid, geog, row_number,
species_positive,
species_negative,
species_treated)
values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16)`,
- values: [
- activityId,
- shortId,
- payload,
- id,
- template.type,
- template.subtype,
- errorRow ? errorRowsBehaviour : desiredFinalStatus,
- userInfo?.preferred_username,
- userInfo?.preferred_username,
- guid,
- guid,
- geog,
- index,
- JSON.stringify(payload['species_positive']),
- JSON.stringify(payload['species_negative']),
- JSON.stringify(payload['species_treated'])
- ]
- };
-
- defaultLog.debug({
- message: 'executing insert for batch',
- params: {
- qc
- }
- });
+ values: [
+ activityId,
+ shortId,
+ payload,
+ id,
+ template.type,
+ template.subtype,
+ errorRow ? errorRowsBehaviour : desiredFinalStatus,
+ userInfo?.preferred_username,
+ userInfo?.preferred_username,
+ guid,
+ guid,
+ geog,
+ index,
+ JSON.stringify(payload['species_positive']),
+ JSON.stringify(payload['species_negative']),
+ JSON.stringify(payload['species_treated'])
+ ]
+ };
- try {
- await dbConnection.query(qc);
- } catch (e) {
defaultLog.debug({
- message: 'error executing insert for batch error->' + JSON.stringify(e)
+ message: 'executing insert for batch',
+ params: {
+ qc
+ }
});
- throw e;
+
+ try {
+ await dbConnection.query(qc);
+ } catch (e) {
+ defaultLog.debug({
+ message: 'error executing insert for batch error->' + JSON.stringify(e)
+ });
+ throw e;
+ }
}
+ } catch (e) {
+ await dbConnection.query('ROLLBACK;');
+ throw e;
}
+ await dbConnection.query('COMMIT;');
+
await dbConnection.query({
text: `UPDATE batch_uploads
diff --git a/app/src/components/batch-upload/BatchDetail.tsx b/app/src/components/batch-upload/BatchDetail.tsx
index 35aef51fc..58f2ab46e 100644
--- a/app/src/components/batch-upload/BatchDetail.tsx
+++ b/app/src/components/batch-upload/BatchDetail.tsx
@@ -152,7 +152,7 @@ const BatchGlobalValidationErrors = ({ batch }) => {
};
const BatchDetail = ({ id }) => {
- const { working, error, item: batch } = useSelector(selectBatch);
+ const { working, error, item: batch, errorMessage } = useSelector(selectBatch);
const dispatch = useDispatch();
useEffect(() => {
@@ -164,7 +164,7 @@ const BatchDetail = ({ id }) => {
return ;
}
if (error) {
- return ;
+ return <>{ errorMessage }>;
}
if (batch == null) {
return No batch found;
diff --git a/app/src/state/reducers/batch.ts b/app/src/state/reducers/batch.ts
index bf3fd3e3a..faf47e0f8 100644
--- a/app/src/state/reducers/batch.ts
+++ b/app/src/state/reducers/batch.ts
@@ -158,6 +158,7 @@ function createBatchReducer() {
...state,
working: false,
error: true,
+ errorMessage: `Could not execute batch ${JSON.stringify(action.payload?.message, null, 2)}`,
item: null
};
case BATCH_EXECUTE_REQUEST:
diff --git a/app/src/state/sagas/batch.ts b/app/src/state/sagas/batch.ts
index 6d6527ebe..2849386c0 100644
--- a/app/src/state/sagas/batch.ts
+++ b/app/src/state/sagas/batch.ts
@@ -13,7 +13,7 @@ import {
BATCH_TEMPLATE_DOWNLOAD_REQUEST,
BATCH_TEMPLATE_DOWNLOAD_SUCCESS,
BATCH_TEMPLATE_LIST_REQUEST,
- BATCH_TEMPLATE_LIST_SUCCESS, BATCH_UPDATE_REQUEST, BATCH_UPDATE_SUCCESS, BATCH_DELETE_ERROR
+ BATCH_TEMPLATE_LIST_SUCCESS, BATCH_UPDATE_REQUEST, BATCH_UPDATE_SUCCESS, BATCH_DELETE_ERROR, BATCH_EXECUTE_ERROR
} from '../actions';
import { Http } from '@capacitor-community/http';
import { actions } from 'components/map/LayerPicker/JSON/actions';
@@ -189,7 +189,7 @@ function* executeBatch(action) {
const { requestHeaders } = yield select(selectAuth);
const { id } = action.payload;
- const { data } = yield Http.request({
+ const {data, status } = yield Http.request({
method: 'POST',
url: configuration.API_BASE + `/api/batch/${id}/execute`,
headers: {
@@ -202,9 +202,16 @@ function* executeBatch(action) {
}
});
- yield put({ type: BATCH_EXECUTE_SUCCESS, payload: data });
- yield put({ type: BATCH_RETRIEVE_REQUEST, payload: { id } });
+ if(!(status < 200 || status > 299))
+ {
+ yield put({ type: BATCH_EXECUTE_SUCCESS, payload: data });
+ yield put({ type: BATCH_RETRIEVE_REQUEST, payload: { id } });
+ }
+ else
+ {
+ yield put({ type: BATCH_EXECUTE_ERROR, payload: data })
+ }
};
function* batchSaga() {