From 00ca70f1c97b943d7d991ce8588f66d7c76a22ca Mon Sep 17 00:00:00 2001 From: Blaine Jester Date: Fri, 16 Dec 2022 09:12:21 -0800 Subject: [PATCH 1/3] Add status code to sentry error messages --- contentcuration/contentcuration/frontend/shared/client.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contentcuration/contentcuration/frontend/shared/client.js b/contentcuration/contentcuration/frontend/shared/client.js index e962e46dd4..53d5bbb309 100644 --- a/contentcuration/contentcuration/frontend/shared/client.js +++ b/contentcuration/contentcuration/frontend/shared/client.js @@ -58,7 +58,7 @@ client.interceptors.response.use( } } - message = message ? `${message}: ${url}` : `Network Error: ${url}`; + message = message ? `${message}: [${status}] ${url}` : `Network Error: [${status}] ${url}`; if (process.env.NODE_ENV !== 'production') { // In dev build log warnings to console for developer use From 646bcb0edc311dd54d34d497b25b5b5ca543046e Mon Sep 17 00:00:00 2001 From: Blaine Jester Date: Fri, 16 Dec 2022 09:13:32 -0800 Subject: [PATCH 2/3] Report disallowed changes to sentry --- .../frontend/shared/data/serverSync.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/contentcuration/contentcuration/frontend/shared/data/serverSync.js b/contentcuration/contentcuration/frontend/shared/data/serverSync.js index e114b8cd19..68b0e7f02b 100644 --- a/contentcuration/contentcuration/frontend/shared/data/serverSync.js +++ b/contentcuration/contentcuration/frontend/shared/data/serverSync.js @@ -1,3 +1,4 @@ +import * as Sentry from '@sentry/vue'; import debounce from 'lodash/debounce'; import findLastIndex from 'lodash/findLastIndex'; import get from 'lodash/get'; @@ -99,6 +100,20 @@ function handleDisallowed(response) { // that were rejected. const disallowed = get(response, ['data', 'disallowed'], []); if (disallowed.length) { + // Capture occurrences of the api disallowing changes + if (process.env.NODE_ENV === 'production') { + Sentry.withScope(function(scope) { + scope.addAttachment({ + filename: 'disallowed.json', + data: JSON.stringify(disallowed), + contentType: 'application/json', + }); + Sentry.captureException(new Error('/api/sync returned disallowed changes')); + }); + } else { + console.warn('/api/sync returned disallowed changes:', disallowed); // eslint-disable-line no-console + } + // Collect all disallowed const disallowedRevs = disallowed.map(d => Number(d.rev)); // Set the return error data onto the changes - this will update the change From bfe94811a6f758b1d22194cbef8d9a427c7cd49c Mon Sep 17 00:00:00 2001 From: Blaine Jester Date: Fri, 16 Dec 2022 09:14:11 -0800 Subject: [PATCH 3/3] Chunk request params when loading clipboard nodes --- .../channelEdit/vuex/clipboard/actions.js | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/contentcuration/contentcuration/frontend/channelEdit/vuex/clipboard/actions.js b/contentcuration/contentcuration/frontend/channelEdit/vuex/clipboard/actions.js index 2358d4ded4..5dd2c62763 100644 --- a/contentcuration/contentcuration/frontend/channelEdit/vuex/clipboard/actions.js +++ b/contentcuration/contentcuration/frontend/channelEdit/vuex/clipboard/actions.js @@ -1,5 +1,6 @@ import get from 'lodash/get'; import partition from 'lodash/partition'; +import chunk from 'lodash/chunk'; import uniq from 'lodash/uniq'; import uniqBy from 'lodash/uniqBy'; import defer from 'lodash/defer'; @@ -83,12 +84,20 @@ export function loadClipboardNodes(context, { parent }) { const legacyNodeIds = legacyNodes.map(n => n.id); return Promise.all([ - context.dispatch( - 'contentNode/loadContentNodes', - { '[node_id+channel_id]__in': nodeIdChannelIdPairs }, - { root } + // To avoid error code 414 URI Too Long errors, we chunk the pairs + // Given URI limit is 2000 chars: + // base URL at 100 chars + each pair at 70 chars = max 27 pairs + ...chunk(nodeIdChannelIdPairs, 25).map(chunkPairs => + context.dispatch( + 'contentNode/loadContentNodes', + { '[node_id+channel_id]__in': chunkPairs }, + { root } + ) + ), + // Chunk legacy nodes, double the size since not pairs + ...chunk(legacyNodeIds, 50).map(legacyChunk => + context.dispatch('contentNode/loadContentNodes', { id__in: legacyChunk }, { root }) ), - context.dispatch('contentNode/loadContentNodes', { id__in: legacyNodeIds }, { root }), ]).then(() => { return context.dispatch('addClipboardNodes', { nodes: clipboardNodes,