payload-plugin-newsletter 0.16.9 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +43 -0
- package/dist/collections.cjs +130 -102
- package/dist/collections.cjs.map +1 -1
- package/dist/collections.js +130 -102
- package/dist/collections.js.map +1 -1
- package/dist/components.cjs +295 -275
- package/dist/components.cjs.map +1 -1
- package/dist/components.js +305 -285
- package/dist/components.js.map +1 -1
- package/dist/index.cjs +175 -104
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +175 -104
- package/dist/index.js.map +1 -1
- package/dist/types.d.cts +7 -0
- package/dist/types.d.ts +7 -0
- package/dist/utils.cjs +64 -28
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.d.cts +1 -0
- package/dist/utils.d.ts +1 -0
- package/dist/utils.js +64 -28
- package/dist/utils.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,46 @@
|
|
|
1
|
+
## [0.17.0] - 2025-07-29
|
|
2
|
+
|
|
3
|
+
### Added
|
|
4
|
+
- **Custom Block Email Converter Support** - Added support for custom block email conversion in broadcasts
|
|
5
|
+
- New `customBlockConverter` option in `BroadcastCustomizations` interface
|
|
6
|
+
- Allows users to provide their own email conversion logic for custom Lexical blocks
|
|
7
|
+
- Converter receives block node and media URL, returns email-safe HTML
|
|
8
|
+
- Supports async operations for fetching external data during conversion
|
|
9
|
+
|
|
10
|
+
- **Server-Side Email Preview Generation** - Implemented server-side email preview for accurate rendering
|
|
11
|
+
- New `/api/broadcasts/preview` endpoint for generating email previews
|
|
12
|
+
- Updated BroadcastInlinePreview component to use server-side preview
|
|
13
|
+
- Ensures preview exactly matches what will be sent via email
|
|
14
|
+
- Custom block converters work in both preview and sent emails
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
- **Email Conversion Functions Now Async** - All email conversion functions are now async to support custom converters
|
|
18
|
+
- `convertToEmailSafeHtml` and all internal converters are now async
|
|
19
|
+
- Maintains backward compatibility - existing code continues to work
|
|
20
|
+
- Enables custom converters to perform async operations like API calls
|
|
21
|
+
|
|
22
|
+
### Technical
|
|
23
|
+
- Updated `convertNode`, `convertParagraph`, `convertHeading`, etc. to be async functions
|
|
24
|
+
- Added `customBlockConverter` parameter throughout the email conversion pipeline
|
|
25
|
+
- Custom converter is called first, falls back to default handling if it returns empty
|
|
26
|
+
- Error handling for custom converter failures with graceful fallback
|
|
27
|
+
- Preview endpoint uses same conversion logic as email sending for consistency
|
|
28
|
+
|
|
29
|
+
## [0.16.10] - 2025-01-29
|
|
30
|
+
|
|
31
|
+
### Fixed
|
|
32
|
+
- **Corrected Syntax Errors** - Fixed TypeScript compilation errors in broadcast afterChange hook
|
|
33
|
+
- Simplified deferred create logic to avoid nested try-catch blocks
|
|
34
|
+
- Removed duplicate error handling and extra braces
|
|
35
|
+
- Fixed all TypeScript compilation errors
|
|
36
|
+
- Maintained functionality for deferred provider sync
|
|
37
|
+
|
|
38
|
+
### Technical
|
|
39
|
+
- Cleaned up afterChange hook structure
|
|
40
|
+
- Simplified error handling flow
|
|
41
|
+
- Removed redundant code blocks
|
|
42
|
+
- All TypeScript errors resolved
|
|
43
|
+
|
|
1
44
|
## [0.16.9] - 2025-01-29
|
|
2
45
|
|
|
3
46
|
### Fixed
|
package/dist/collections.cjs
CHANGED
|
@@ -963,62 +963,73 @@ async function convertToEmailSafeHtml(editorState, options) {
|
|
|
963
963
|
if (!editorState) {
|
|
964
964
|
return "";
|
|
965
965
|
}
|
|
966
|
-
const rawHtml = await lexicalToEmailHtml(editorState, options?.mediaUrl);
|
|
966
|
+
const rawHtml = await lexicalToEmailHtml(editorState, options?.mediaUrl, options?.customBlockConverter);
|
|
967
967
|
const sanitizedHtml = import_isomorphic_dompurify.default.sanitize(rawHtml, EMAIL_SAFE_CONFIG);
|
|
968
968
|
if (options?.wrapInTemplate) {
|
|
969
969
|
return wrapInEmailTemplate(sanitizedHtml, options.preheader);
|
|
970
970
|
}
|
|
971
971
|
return sanitizedHtml;
|
|
972
972
|
}
|
|
973
|
-
async function lexicalToEmailHtml(editorState, mediaUrl) {
|
|
973
|
+
async function lexicalToEmailHtml(editorState, mediaUrl, customBlockConverter) {
|
|
974
974
|
const { root } = editorState;
|
|
975
975
|
if (!root || !root.children) {
|
|
976
976
|
return "";
|
|
977
977
|
}
|
|
978
|
-
const
|
|
979
|
-
|
|
978
|
+
const htmlParts = await Promise.all(
|
|
979
|
+
root.children.map((node) => convertNode(node, mediaUrl, customBlockConverter))
|
|
980
|
+
);
|
|
981
|
+
return htmlParts.join("");
|
|
980
982
|
}
|
|
981
|
-
function convertNode(node, mediaUrl) {
|
|
983
|
+
async function convertNode(node, mediaUrl, customBlockConverter) {
|
|
982
984
|
switch (node.type) {
|
|
983
985
|
case "paragraph":
|
|
984
|
-
return convertParagraph(node, mediaUrl);
|
|
986
|
+
return convertParagraph(node, mediaUrl, customBlockConverter);
|
|
985
987
|
case "heading":
|
|
986
|
-
return convertHeading(node, mediaUrl);
|
|
988
|
+
return convertHeading(node, mediaUrl, customBlockConverter);
|
|
987
989
|
case "list":
|
|
988
|
-
return convertList(node, mediaUrl);
|
|
990
|
+
return convertList(node, mediaUrl, customBlockConverter);
|
|
989
991
|
case "listitem":
|
|
990
|
-
return convertListItem(node, mediaUrl);
|
|
992
|
+
return convertListItem(node, mediaUrl, customBlockConverter);
|
|
991
993
|
case "blockquote":
|
|
992
|
-
return convertBlockquote(node, mediaUrl);
|
|
994
|
+
return convertBlockquote(node, mediaUrl, customBlockConverter);
|
|
993
995
|
case "text":
|
|
994
996
|
return convertText(node);
|
|
995
997
|
case "link":
|
|
996
|
-
return convertLink(node, mediaUrl);
|
|
998
|
+
return convertLink(node, mediaUrl, customBlockConverter);
|
|
997
999
|
case "linebreak":
|
|
998
1000
|
return "<br>";
|
|
999
1001
|
case "upload":
|
|
1000
1002
|
return convertUpload(node, mediaUrl);
|
|
1001
1003
|
case "block":
|
|
1002
|
-
return convertBlock(node, mediaUrl);
|
|
1004
|
+
return await convertBlock(node, mediaUrl, customBlockConverter);
|
|
1003
1005
|
default:
|
|
1004
1006
|
if (node.children) {
|
|
1005
|
-
|
|
1007
|
+
const childParts = await Promise.all(
|
|
1008
|
+
node.children.map((child) => convertNode(child, mediaUrl, customBlockConverter))
|
|
1009
|
+
);
|
|
1010
|
+
return childParts.join("");
|
|
1006
1011
|
}
|
|
1007
1012
|
return "";
|
|
1008
1013
|
}
|
|
1009
1014
|
}
|
|
1010
|
-
function convertParagraph(node, mediaUrl) {
|
|
1015
|
+
async function convertParagraph(node, mediaUrl, customBlockConverter) {
|
|
1011
1016
|
const align = getAlignment(node.format);
|
|
1012
|
-
const
|
|
1017
|
+
const childParts = await Promise.all(
|
|
1018
|
+
(node.children || []).map((child) => convertNode(child, mediaUrl, customBlockConverter))
|
|
1019
|
+
);
|
|
1020
|
+
const children = childParts.join("");
|
|
1013
1021
|
if (!children.trim()) {
|
|
1014
1022
|
return '<p style="margin: 0 0 16px 0; min-height: 1em;"> </p>';
|
|
1015
1023
|
}
|
|
1016
1024
|
return `<p style="margin: 0 0 16px 0; text-align: ${align};">${children}</p>`;
|
|
1017
1025
|
}
|
|
1018
|
-
function convertHeading(node, mediaUrl) {
|
|
1026
|
+
async function convertHeading(node, mediaUrl, customBlockConverter) {
|
|
1019
1027
|
const tag = node.tag || "h1";
|
|
1020
1028
|
const align = getAlignment(node.format);
|
|
1021
|
-
const
|
|
1029
|
+
const childParts = await Promise.all(
|
|
1030
|
+
(node.children || []).map((child) => convertNode(child, mediaUrl, customBlockConverter))
|
|
1031
|
+
);
|
|
1032
|
+
const children = childParts.join("");
|
|
1022
1033
|
const styles2 = {
|
|
1023
1034
|
h1: "font-size: 32px; font-weight: 700; margin: 0 0 24px 0; line-height: 1.2;",
|
|
1024
1035
|
h2: "font-size: 24px; font-weight: 600; margin: 0 0 16px 0; line-height: 1.3;",
|
|
@@ -1027,18 +1038,27 @@ function convertHeading(node, mediaUrl) {
|
|
|
1027
1038
|
const style = `${styles2[tag] || styles2.h3} text-align: ${align};`;
|
|
1028
1039
|
return `<${tag} style="${style}">${children}</${tag}>`;
|
|
1029
1040
|
}
|
|
1030
|
-
function convertList(node, mediaUrl) {
|
|
1041
|
+
async function convertList(node, mediaUrl, customBlockConverter) {
|
|
1031
1042
|
const tag = node.listType === "number" ? "ol" : "ul";
|
|
1032
|
-
const
|
|
1043
|
+
const childParts = await Promise.all(
|
|
1044
|
+
(node.children || []).map((child) => convertNode(child, mediaUrl, customBlockConverter))
|
|
1045
|
+
);
|
|
1046
|
+
const children = childParts.join("");
|
|
1033
1047
|
const style = tag === "ul" ? "margin: 0 0 16px 0; padding-left: 24px; list-style-type: disc;" : "margin: 0 0 16px 0; padding-left: 24px; list-style-type: decimal;";
|
|
1034
1048
|
return `<${tag} style="${style}">${children}</${tag}>`;
|
|
1035
1049
|
}
|
|
1036
|
-
function convertListItem(node, mediaUrl) {
|
|
1037
|
-
const
|
|
1050
|
+
async function convertListItem(node, mediaUrl, customBlockConverter) {
|
|
1051
|
+
const childParts = await Promise.all(
|
|
1052
|
+
(node.children || []).map((child) => convertNode(child, mediaUrl, customBlockConverter))
|
|
1053
|
+
);
|
|
1054
|
+
const children = childParts.join("");
|
|
1038
1055
|
return `<li style="margin: 0 0 8px 0;">${children}</li>`;
|
|
1039
1056
|
}
|
|
1040
|
-
function convertBlockquote(node, mediaUrl) {
|
|
1041
|
-
const
|
|
1057
|
+
async function convertBlockquote(node, mediaUrl, customBlockConverter) {
|
|
1058
|
+
const childParts = await Promise.all(
|
|
1059
|
+
(node.children || []).map((child) => convertNode(child, mediaUrl, customBlockConverter))
|
|
1060
|
+
);
|
|
1061
|
+
const children = childParts.join("");
|
|
1042
1062
|
const style = "margin: 0 0 16px 0; padding-left: 16px; border-left: 4px solid #e5e7eb; color: #6b7280;";
|
|
1043
1063
|
return `<blockquote style="${style}">${children}</blockquote>`;
|
|
1044
1064
|
}
|
|
@@ -1058,8 +1078,11 @@ function convertText(node) {
|
|
|
1058
1078
|
}
|
|
1059
1079
|
return text;
|
|
1060
1080
|
}
|
|
1061
|
-
function convertLink(node, mediaUrl) {
|
|
1062
|
-
const
|
|
1081
|
+
async function convertLink(node, mediaUrl, customBlockConverter) {
|
|
1082
|
+
const childParts = await Promise.all(
|
|
1083
|
+
(node.children || []).map((child) => convertNode(child, mediaUrl, customBlockConverter))
|
|
1084
|
+
);
|
|
1085
|
+
const children = childParts.join("");
|
|
1063
1086
|
const url = node.fields?.url || "#";
|
|
1064
1087
|
const newTab = node.fields?.newTab ?? false;
|
|
1065
1088
|
const targetAttr = newTab ? ' target="_blank"' : "";
|
|
@@ -1090,8 +1113,18 @@ function convertUpload(node, mediaUrl) {
|
|
|
1090
1113
|
}
|
|
1091
1114
|
return `<div style="margin: 0 0 16px 0; text-align: center;">${imgHtml}</div>`;
|
|
1092
1115
|
}
|
|
1093
|
-
function convertBlock(node, mediaUrl) {
|
|
1094
|
-
const blockType = node.fields?.blockName;
|
|
1116
|
+
async function convertBlock(node, mediaUrl, customBlockConverter) {
|
|
1117
|
+
const blockType = node.fields?.blockName || node.blockName;
|
|
1118
|
+
if (customBlockConverter) {
|
|
1119
|
+
try {
|
|
1120
|
+
const customHtml = await customBlockConverter(node, mediaUrl);
|
|
1121
|
+
if (customHtml) {
|
|
1122
|
+
return customHtml;
|
|
1123
|
+
}
|
|
1124
|
+
} catch (error) {
|
|
1125
|
+
console.error(`Custom block converter error for ${blockType}:`, error);
|
|
1126
|
+
}
|
|
1127
|
+
}
|
|
1095
1128
|
switch (blockType) {
|
|
1096
1129
|
case "button":
|
|
1097
1130
|
return convertButtonBlock(node.fields);
|
|
@@ -1099,7 +1132,10 @@ function convertBlock(node, mediaUrl) {
|
|
|
1099
1132
|
return convertDividerBlock(node.fields);
|
|
1100
1133
|
default:
|
|
1101
1134
|
if (node.children) {
|
|
1102
|
-
|
|
1135
|
+
const childParts = await Promise.all(
|
|
1136
|
+
node.children.map((child) => convertNode(child, mediaUrl, customBlockConverter))
|
|
1137
|
+
);
|
|
1138
|
+
return childParts.join("");
|
|
1103
1139
|
}
|
|
1104
1140
|
return "";
|
|
1105
1141
|
}
|
|
@@ -1473,7 +1509,9 @@ var createBroadcastsCollection = (pluginConfig) => {
|
|
|
1473
1509
|
const { BroadcastApiProvider: BroadcastApiProvider2 } = await Promise.resolve().then(() => (init_broadcast2(), broadcast_exports));
|
|
1474
1510
|
const provider = new BroadcastApiProvider2(providerConfig);
|
|
1475
1511
|
req.payload.logger.info("Converting content to HTML...");
|
|
1476
|
-
const htmlContent = await convertToEmailSafeHtml(doc.contentSection?.content
|
|
1512
|
+
const htmlContent = await convertToEmailSafeHtml(doc.contentSection?.content, {
|
|
1513
|
+
customBlockConverter: pluginConfig.customizations?.broadcasts?.customBlockConverter
|
|
1514
|
+
});
|
|
1477
1515
|
if (!htmlContent || htmlContent.trim() === "") {
|
|
1478
1516
|
req.payload.logger.info("Skipping provider sync - content is empty after conversion");
|
|
1479
1517
|
return doc;
|
|
@@ -1569,77 +1607,49 @@ var createBroadcastsCollection = (pluginConfig) => {
|
|
|
1569
1607
|
req.payload.logger.info("Still missing required fields for provider sync");
|
|
1570
1608
|
return doc;
|
|
1571
1609
|
}
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
}
|
|
1579
|
-
const createData = {
|
|
1580
|
-
name: doc.subject,
|
|
1581
|
-
subject: doc.subject,
|
|
1582
|
-
preheader: doc.contentSection?.preheader,
|
|
1583
|
-
content: htmlContent,
|
|
1584
|
-
trackOpens: doc.settings?.trackOpens,
|
|
1585
|
-
trackClicks: doc.settings?.trackClicks,
|
|
1586
|
-
replyTo: doc.settings?.replyTo || providerConfig.replyTo,
|
|
1587
|
-
audienceIds: doc.audienceIds?.map((a) => a.audienceId)
|
|
1588
|
-
};
|
|
1589
|
-
req.payload.logger.info("Creating broadcast with data:", {
|
|
1590
|
-
name: createData.name,
|
|
1591
|
-
subject: createData.subject,
|
|
1592
|
-
preheader: createData.preheader || "NONE",
|
|
1593
|
-
contentLength: htmlContent ? htmlContent.length : 0,
|
|
1594
|
-
contentPreview: htmlContent ? htmlContent.substring(0, 100) + "..." : "EMPTY",
|
|
1595
|
-
apiUrl: providerConfig.apiUrl,
|
|
1596
|
-
hasToken: !!providerConfig.token
|
|
1597
|
-
});
|
|
1598
|
-
const providerBroadcast = await provider.create(createData);
|
|
1599
|
-
await req.payload.update({
|
|
1600
|
-
collection: "broadcasts",
|
|
1601
|
-
id: doc.id,
|
|
1602
|
-
data: {
|
|
1603
|
-
providerId: providerBroadcast.id,
|
|
1604
|
-
providerData: providerBroadcast.providerData
|
|
1605
|
-
},
|
|
1606
|
-
req
|
|
1607
|
-
});
|
|
1608
|
-
req.payload.logger.info(`Broadcast ${doc.id} created in provider successfully (deferred)`);
|
|
1609
|
-
return {
|
|
1610
|
-
...doc,
|
|
1611
|
-
providerId: providerBroadcast.id,
|
|
1612
|
-
providerData: providerBroadcast.providerData
|
|
1613
|
-
};
|
|
1614
|
-
} catch (error) {
|
|
1615
|
-
req.payload.logger.error("Raw error from broadcast provider (deferred create):");
|
|
1616
|
-
req.payload.logger.error(error);
|
|
1617
|
-
if (error instanceof Error) {
|
|
1618
|
-
req.payload.logger.error("Error is instance of Error:", {
|
|
1619
|
-
message: error.message,
|
|
1620
|
-
stack: error.stack,
|
|
1621
|
-
name: error.name,
|
|
1622
|
-
...error.details,
|
|
1623
|
-
...error.response,
|
|
1624
|
-
...error.data,
|
|
1625
|
-
...error.status,
|
|
1626
|
-
...error.statusText
|
|
1627
|
-
});
|
|
1628
|
-
} else if (typeof error === "string") {
|
|
1629
|
-
req.payload.logger.error("Error is a string:", error);
|
|
1630
|
-
} else if (error && typeof error === "object") {
|
|
1631
|
-
req.payload.logger.error("Error is an object:", JSON.stringify(error, null, 2));
|
|
1632
|
-
} else {
|
|
1633
|
-
req.payload.logger.error("Unknown error type:", typeof error);
|
|
1634
|
-
}
|
|
1635
|
-
req.payload.logger.error("Failed broadcast document (deferred create):", {
|
|
1636
|
-
id: doc.id,
|
|
1637
|
-
subject: doc.subject,
|
|
1638
|
-
hasContent: !!doc.contentSection?.content,
|
|
1639
|
-
contentType: doc.contentSection?.content ? typeof doc.contentSection.content : "none"
|
|
1640
|
-
});
|
|
1610
|
+
req.payload.logger.info("Creating broadcast in provider (deferred from initial create)...");
|
|
1611
|
+
const htmlContent = await convertToEmailSafeHtml(doc.contentSection?.content, {
|
|
1612
|
+
customBlockConverter: pluginConfig.customizations?.broadcasts?.customBlockConverter
|
|
1613
|
+
});
|
|
1614
|
+
if (!htmlContent || htmlContent.trim() === "") {
|
|
1615
|
+
req.payload.logger.info("Skipping provider sync - content is empty after conversion");
|
|
1641
1616
|
return doc;
|
|
1642
1617
|
}
|
|
1618
|
+
const createData = {
|
|
1619
|
+
name: doc.subject,
|
|
1620
|
+
subject: doc.subject,
|
|
1621
|
+
preheader: doc.contentSection?.preheader,
|
|
1622
|
+
content: htmlContent,
|
|
1623
|
+
trackOpens: doc.settings?.trackOpens,
|
|
1624
|
+
trackClicks: doc.settings?.trackClicks,
|
|
1625
|
+
replyTo: doc.settings?.replyTo || providerConfig.replyTo,
|
|
1626
|
+
audienceIds: doc.audienceIds?.map((a) => a.audienceId)
|
|
1627
|
+
};
|
|
1628
|
+
req.payload.logger.info("Creating broadcast with data:", {
|
|
1629
|
+
name: createData.name,
|
|
1630
|
+
subject: createData.subject,
|
|
1631
|
+
preheader: createData.preheader || "NONE",
|
|
1632
|
+
contentLength: htmlContent ? htmlContent.length : 0,
|
|
1633
|
+
contentPreview: htmlContent ? htmlContent.substring(0, 100) + "..." : "EMPTY",
|
|
1634
|
+
apiUrl: providerConfig.apiUrl,
|
|
1635
|
+
hasToken: !!providerConfig.token
|
|
1636
|
+
});
|
|
1637
|
+
const providerBroadcast = await provider.create(createData);
|
|
1638
|
+
await req.payload.update({
|
|
1639
|
+
collection: "broadcasts",
|
|
1640
|
+
id: doc.id,
|
|
1641
|
+
data: {
|
|
1642
|
+
providerId: providerBroadcast.id,
|
|
1643
|
+
providerData: providerBroadcast.providerData
|
|
1644
|
+
},
|
|
1645
|
+
req
|
|
1646
|
+
});
|
|
1647
|
+
req.payload.logger.info(`Broadcast ${doc.id} created in provider successfully (deferred)`);
|
|
1648
|
+
return {
|
|
1649
|
+
...doc,
|
|
1650
|
+
providerId: providerBroadcast.id,
|
|
1651
|
+
providerData: providerBroadcast.providerData
|
|
1652
|
+
};
|
|
1643
1653
|
}
|
|
1644
1654
|
if (doc.providerId) {
|
|
1645
1655
|
const capabilities = provider.getCapabilities();
|
|
@@ -1659,7 +1669,9 @@ var createBroadcastsCollection = (pluginConfig) => {
|
|
|
1659
1669
|
updates.preheader = doc.contentSection?.preheader;
|
|
1660
1670
|
}
|
|
1661
1671
|
if (JSON.stringify(doc.contentSection?.content) !== JSON.stringify(previousDoc?.contentSection?.content)) {
|
|
1662
|
-
updates.content = await convertToEmailSafeHtml(doc.contentSection?.content
|
|
1672
|
+
updates.content = await convertToEmailSafeHtml(doc.contentSection?.content, {
|
|
1673
|
+
customBlockConverter: pluginConfig.customizations?.broadcasts?.customBlockConverter
|
|
1674
|
+
});
|
|
1663
1675
|
}
|
|
1664
1676
|
if (doc.settings?.trackOpens !== previousDoc?.settings?.trackOpens) {
|
|
1665
1677
|
updates.trackOpens = doc.settings.trackOpens;
|
|
@@ -1684,16 +1696,32 @@ var createBroadcastsCollection = (pluginConfig) => {
|
|
|
1684
1696
|
}
|
|
1685
1697
|
}
|
|
1686
1698
|
} catch (error) {
|
|
1699
|
+
req.payload.logger.error("Raw error from broadcast update operation:");
|
|
1700
|
+
req.payload.logger.error(error);
|
|
1687
1701
|
if (error instanceof Error) {
|
|
1688
|
-
req.payload.logger.error("
|
|
1702
|
+
req.payload.logger.error("Error is instance of Error:", {
|
|
1689
1703
|
message: error.message,
|
|
1690
1704
|
stack: error.stack,
|
|
1691
1705
|
name: error.name,
|
|
1692
|
-
...error.details
|
|
1706
|
+
...error.details,
|
|
1707
|
+
...error.response,
|
|
1708
|
+
...error.data,
|
|
1709
|
+
...error.status,
|
|
1710
|
+
...error.statusText
|
|
1693
1711
|
});
|
|
1712
|
+
} else if (typeof error === "string") {
|
|
1713
|
+
req.payload.logger.error("Error is a string:", error);
|
|
1714
|
+
} else if (error && typeof error === "object") {
|
|
1715
|
+
req.payload.logger.error("Error is an object:", JSON.stringify(error, null, 2));
|
|
1694
1716
|
} else {
|
|
1695
|
-
req.payload.logger.error("
|
|
1717
|
+
req.payload.logger.error("Unknown error type:", typeof error);
|
|
1696
1718
|
}
|
|
1719
|
+
req.payload.logger.error("Failed broadcast document (update operation):", {
|
|
1720
|
+
id: doc.id,
|
|
1721
|
+
subject: doc.subject,
|
|
1722
|
+
hasContent: !!doc.contentSection?.content,
|
|
1723
|
+
contentType: doc.contentSection?.content ? typeof doc.contentSection.content : "none"
|
|
1724
|
+
});
|
|
1697
1725
|
}
|
|
1698
1726
|
}
|
|
1699
1727
|
return doc;
|