From 8043494798fc34c977d39d996c26001c77d2ea37 Mon Sep 17 00:00:00 2001 From: Neeha2383 Date: Mon, 14 Sep 2026 10:14:15 -0600 Subject: [PATCH 1/2] fix(content-import): validate Content Type before streaming sample CSV (#37461) Clicking "download a CSV sample file" with no Content Type selected threw after the attachment headers were committed, returning an empty 500 the browser rendered as an error page. Guard the action (reusing the preview branch's structure-type-is-required message) and validate client-side before submitting. Refs: #37461 --- .../contentlet/action/ImportContentletsAction.java | 14 +++++++++++--- .../portlet/ext/contentlet/import_contentlets.jsp | 5 +++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/dotCMS/src/main/java/com/dotmarketing/portlets/contentlet/action/ImportContentletsAction.java b/dotCMS/src/main/java/com/dotmarketing/portlets/contentlet/action/ImportContentletsAction.java index 5516572e96fa..e11d270330bc 100644 --- a/dotCMS/src/main/java/com/dotmarketing/portlets/contentlet/action/ImportContentletsAction.java +++ b/dotCMS/src/main/java/com/dotmarketing/portlets/contentlet/action/ImportContentletsAction.java @@ -376,13 +376,21 @@ private void _downloadCSVTemplate(ActionRequest req, ActionResponse res, Portlet ActionResponseImpl resImpl = (ActionResponseImpl)res; HttpServletResponse httpRes = resImpl.getHttpServletResponse(); + ImportContentletsForm importForm = (ImportContentletsForm) form; + if (!UtilMethods.isSet(importForm.getStructure())) { + SessionMessages.add(req, ERROR, "structure-type-is-required"); + setForward(req, PORTLET_EXT_CONTENTLET_IMPORT_CONTENTLETS); + return; + } + + // The fields must be resolved before any download header is committed, otherwise a + // failed lookup leaves the response flagged as an attachment with an empty error body + List fields = FieldsCache.getFieldsByStructureInode(importForm.getStructure()); + httpRes.setContentType("application/octet-stream"); httpRes.setHeader("Content-Disposition", "attachment; filename=\"CSV_Template.csv\""); ServletOutputStream out = httpRes.getOutputStream(); - ImportContentletsForm importForm = (ImportContentletsForm) form; - - List fields = FieldsCache.getFieldsByStructureInode(importForm.getStructure()); for(int i = 0; i < fields.size(); i++) { Field field = fields.get(i); if (ImportUtil.isImportableField(field)) { diff --git a/dotCMS/src/main/webapp/html/portlet/ext/contentlet/import_contentlets.jsp b/dotCMS/src/main/webapp/html/portlet/ext/contentlet/import_contentlets.jsp index 03da207db08f..8b3f44d865ef 100644 --- a/dotCMS/src/main/webapp/html/portlet/ext/contentlet/import_contentlets.jsp +++ b/dotCMS/src/main/webapp/html/portlet/ext/contentlet/import_contentlets.jsp @@ -127,6 +127,11 @@ } function downloadCSVExample() { + var structureInode = dijit.byId("structuresSelect").attr('value'); + if (!structureInode) { + showDotCMSSystemMessage('<%= UtilMethods.escapeSingleQuotes(LanguageUtil.get(pageContext, "structure-type-is-required")) %>', true); + return; + } var href = ''; href += ''; href += ''; From bdea283c68ae070a5b53fa0b295a1ad2aa5e6915 Mon Sep 17 00:00:00 2001 From: Neeha2383 Date: Thu, 17 Sep 2026 10:37:44 -0600 Subject: [PATCH 2/2] fix(content-import): show friendly message when selected Content Type no longer exists (#37461) Addresses PR review feedback: a set-but-nonexistent structure inode (type deleted after the screen loaded, or a crafted request) made the fields lookup throw to an error page. Catch the lookup failure and re-render the import screen with the existing Content-Type-does-not-exist message. Refs: #37461 --- .../contentlet/action/ImportContentletsAction.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/dotCMS/src/main/java/com/dotmarketing/portlets/contentlet/action/ImportContentletsAction.java b/dotCMS/src/main/java/com/dotmarketing/portlets/contentlet/action/ImportContentletsAction.java index e11d270330bc..374cc35a86c3 100644 --- a/dotCMS/src/main/java/com/dotmarketing/portlets/contentlet/action/ImportContentletsAction.java +++ b/dotCMS/src/main/java/com/dotmarketing/portlets/contentlet/action/ImportContentletsAction.java @@ -15,6 +15,7 @@ import com.dotmarketing.business.CacheLocator; import com.dotmarketing.cache.FieldsCache; import com.dotmarketing.db.HibernateUtil; +import com.dotmarketing.business.DotStateException; import com.dotmarketing.exception.DotHibernateException; import com.dotmarketing.portal.struts.DotPortletAction; import com.dotmarketing.portlets.contentlet.action.ImportAuditUtil.ImportAuditResults; @@ -385,7 +386,15 @@ private void _downloadCSVTemplate(ActionRequest req, ActionResponse res, Portlet // The fields must be resolved before any download header is committed, otherwise a // failed lookup leaves the response flagged as an attachment with an empty error body - List fields = FieldsCache.getFieldsByStructureInode(importForm.getStructure()); + final List fields; + try { + fields = FieldsCache.getFieldsByStructureInode(importForm.getStructure()); + } catch (final DotStateException e) { + Logger.warn(this, "Unable to generate CSV template: selected Content Type does not exist", e); + SessionMessages.add(req, ERROR, "Workflow-does-not-exists-content-type"); + setForward(req, PORTLET_EXT_CONTENTLET_IMPORT_CONTENTLETS); + return; + } httpRes.setContentType("application/octet-stream"); httpRes.setHeader("Content-Disposition", "attachment; filename=\"CSV_Template.csv\"");