Skip to content
19 changes: 14 additions & 5 deletions packages/strapi-connector-bookshelf/lib/queries.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const pmap = require('p-map');
const { convertRestQueryParams, buildQuery, escapeQuery } = require('strapi-utils');
const { contentTypes: contentTypesUtils } = require('strapi-utils');
const { singular } = require('pluralize');
const { handleDatabaseError } = require('./utils/errors');

const { PUBLISHED_AT_ATTRIBUTE } = contentTypesUtils.constants;
const pickCountFilters = omit(['sort', 'limit', 'start']);
Expand Down Expand Up @@ -50,6 +51,14 @@ module.exports = function createQueryBuilder({ model, strapi }) {
return db.transaction(trx => fn(trx));
};

const wrapErrors = fn => async (...args) => {
try {
return await fn(...args);
} catch (error) {
return handleDatabaseError(error);
}
};

/**
* Find one entry based on params
*/
Expand Down Expand Up @@ -138,7 +147,7 @@ module.exports = function createQueryBuilder({ model, strapi }) {
return model.updateRelations({ id: entry.id, values: relations }, { transacting: trx });
}

return this.findOne(params, null, { transacting: trx });
return findOne(params, null, { transacting: trx });
};

return wrapTransaction(runUpdate, { transacting });
Expand Down Expand Up @@ -461,7 +470,7 @@ module.exports = function createQueryBuilder({ model, strapi }) {
};
});

// verify the provided ids are realted to this entity.
// verify the provided ids are related to this entity.
idsToKeep.forEach(({ id, component }) => {
if (!allIds.find(el => el.id === id && el.component.uid === component.uid)) {
const err = new Error(
Expand Down Expand Up @@ -523,7 +532,7 @@ module.exports = function createQueryBuilder({ model, strapi }) {
.fetchAll({ transacting })
.map(el => el.get('component_id').toString());

// verify the provided ids are realted to this entity.
// verify the provided ids are related to this entity.
idsToKeep.forEach(id => {
if (!allIds.includes(id)) {
const err = new Error(
Expand Down Expand Up @@ -667,8 +676,8 @@ module.exports = function createQueryBuilder({ model, strapi }) {
return {
findOne,
find,
create,
update,
create: wrapErrors(create),
update: wrapErrors(update),
delete: deleteMany,
count,
search,
Expand Down
32 changes: 32 additions & 0 deletions packages/strapi-connector-bookshelf/lib/utils/errors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
'use strict';

const isDuplicateEntryError = error => {
// postgres
if (error.code === '23505') {
return true;
}

// mysql
if (error.code === 'ER_DUP_ENTRY') {
return true;
}

// sqlite
if (error.toString().includes('SQLITE_CONSTRAINT: UNIQUE')) {
return true;
}

return false;
};

const handleDatabaseError = error => {
if (isDuplicateEntryError(error)) {
strapi.log.warn('Duplicate entry', error.toString());
throw new Error('Duplicate entry');
}
throw error;
};

module.exports = {
handleDatabaseError,
};
15 changes: 12 additions & 3 deletions packages/strapi-connector-mongoose/lib/queries.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ const mongoose = require('mongoose');
const populateQueries = require('./utils/populate-queries');

const { PUBLISHED_AT_ATTRIBUTE, DP_PUB_STATES } = contentTypesUtils.constants;

const { findComponentByGlobalId } = require('./utils/helpers');
const { handleDatabaseError } = require('./utils/errors');

const hasPK = (obj, model) => _.has(obj, model.primaryKey) || _.has(obj, 'id');
const getPK = (obj, model) => (_.has(obj, model.primaryKey) ? obj[model.primaryKey] : obj.id);
Expand Down Expand Up @@ -58,6 +58,15 @@ module.exports = ({ model, strapi }) => {
const omitExernalValues = values => {
return _.omit(values, excludedKeys);
};

const wrapErrors = fn => async (...args) => {
try {
return await fn(...args);
} catch (error) {
return handleDatabaseError(error);
}
};

async function createComponents(entry, values, { isDraft, session = null } = {}) {
if (componentKeys.length === 0) return;

Expand Down Expand Up @@ -594,8 +603,8 @@ module.exports = ({ model, strapi }) => {
return {
findOne,
find,
create,
update,
create: wrapErrors(create),
update: wrapErrors(update),
delete: deleteMany,
count,
search,
Expand Down
17 changes: 17 additions & 0 deletions packages/strapi-connector-mongoose/lib/utils/errors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
'use strict';

const isDuplicateEntryError = error => {
return error.code === 11000; // MongoDB code for duplicate key error
};

const handleDatabaseError = error => {
if (isDuplicateEntryError(error)) {
strapi.log.warn('Duplicate entry', error.toString());
throw new Error('Duplicate entry');
}
throw error;
};

module.exports = {
handleDatabaseError,
};