Skip to content

docs(web/guides): fix sending-email mailer pattern, attachment paths, and SMTP defaults wording - #3093

Merged
bpamiri merged 1 commit into
developfrom
peter/docs-audit2-sending-email
Jun 12, 2026
Merged

docs(web/guides): fix sending-email mailer pattern, attachment paths, and SMTP defaults wording#3093
bpamiri merged 1 commit into
developfrom
peter/docs-audit2-sending-email

Conversation

@bpamiri

@bpamiri bpamiri commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

Summary

Guide-behavioral-audit P1 batch 2 (work item p1-7-email) corrections to digging-deeper/sending-email.mdx. Each fix documents current behavior verified live on Lucee 7 and/or Adobe 2023; the one broken-but-unfixed framework gap is cited as an issue, not papered over.

Corrections

  1. Mailer-CFC pattern rewritten to a working form (claim email-08-mailer-cfc-pattern, docs-wrong; verified on Lucee 7 + Adobe 2023). The page's centerpiece new wheels.Controller().sendEmail(...) pattern throws HTTP 500 on every engine — a bare controller instance has no variables.params, and $renderView$generateIncludeTemplatePath (rendering.cfc:575) dereferences it even for absolute template= paths (Lucee: "has no accessible Member with name [PARAMS]"; Adobe: "Element PARAMS is undefined"). Both UserMailer methods now use the verified new wheels.Global().controller(name=..., params=...) factory (returned struct had correct subject/to/body on both engines), with a caution Aside explaining the failure and citing sending-email guide's mailer pattern new wheels.Controller().sendEmail() throws on every engine (no variables.params) — fix docs and/or harden $renderView for out-of-request senders #3078 for the optional out-of-request sendEmail() hardening.

  2. Attachment examples no longer contradict the resolution rule (claim email-21-guide-examples-contain-slashes-DOC-BUG, docs-wrong; verified Lucee 7). The prose said "paths without a slash resolve relative to filePath," but both examples used invoices/... paths — which the slash check (miscellaneous.cfc:152) passes through to cfmailparam unchanged, resolving against the JVM working directory at delivery time. Examples switched to bare filenames; prose tightened to "without any directory separator (/ or \)" and now explains the pass-through behavior plus an ExpandPath() escape hatch. Also fixes the email-20 nit: filePath default files expands relative to the web root (public/files/ in the v4 template), not "files/ at the app root."

  3. from removed from the sendEmail defaults examples (claim email-26-from-default-vs-required-signature, docs-wrong; verified Lucee 7 + Adobe 2023). from/to/subject are required parameters (miscellaneous.cfc:22-24), so the engine throws a missing-parameter error before $args can apply a configured default — a from default is never honored. Dropped from= from the config/settings.cfm and config/production/settings.cfm set(functionName="sendEmail", ...) blocks and added a paragraph documenting why those three can't be defaulted.

  4. SMTP-blocking wording corrected (claim email-11-synchronous-blocks-on-smtp evidence). "the user's browser waits for SMTP to hand off the message" overstated the default: cfmail spools to disk by default on Lucee and Adobe, so the request normally pays render + compose + spool, not the SMTP handoff. Reworded; the push-to-a-job advice stands.

Verification

  • pnpm verify:docs src/content/docs/v4-0-0/digging-deeper/sending-email.mdx → 11 tagged blocks, 11 passed, exit 0.

Refs #3078

🤖 Generated with Claude Code

…paths, and SMTP wording

Behavioral audit (P1 batch 2, p1-7-email) corrections to
digging-deeper/sending-email.mdx:

- Mailer pattern: replace new wheels.Controller().sendEmail(...) — throws
  on every engine (no variables.params) — with the verified
  controller(name, params) factory form; add a caution citing #3078.
- Attachments: examples used slash-containing paths that skip filePath
  resolution; switch to bare filenames, document the separator rule and
  that filePath expands relative to the web root (public/files/).
- sendEmail defaults: from/to/subject are engine-required parameters, so
  configured defaults for them never apply; drop from= from both
  set(functionName="sendEmail", ...) examples and document why.
- Background-job rationale: cfmail spools by default, so the request does
  not normally wait for the SMTP handoff; reword the latency claim.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Peter Amiri <peter@alurium.com>

@wheels-bot wheels-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wheels Bot — Reviewer

TL;DR: This docs-only PR fixes four behavioral inaccuracies in the v4 digging-deeper/sending-email.mdx guide (broken mailer-CFC pattern, contradictory attachment examples, never-honored from default, overstated SMTP latency claim). I verified every technical claim in the diff against the framework source and all of them are accurate. Verdict: comment — no blocking findings, one minor non-blocking observation below.

Verification of the diff's claims (all confirmed)

Claim in diff Framework evidence
from/to/subject are engine-required, so configured defaults for them never apply vendor/wheels/controller/miscellaneous.cfc:22-24required string from, required string to, required string subject; the engine enforces these before $args() (line 32) runs
new wheels.Controller().sendEmail(...) throws because the rendering pipeline dereferences variables.params even for absolute template paths vendor/wheels/controller/rendering.cfc:577$generateIncludeTemplatePath declares the default argument $controllerName = variables.params.controller, evaluated regardless of whether $name is absolute
controller(name, params) factory builds a request-capable instance, and works without a Mailer.cfc existing vendor/wheels/Global.cfc:1209 (factory; instantiates via $createControllerObject(params) when params is non-empty) and Global.cfc:1135 (falls back to the base Controller when no controller file is found on any path). Same pattern used throughout vendor/wheels/tests/specs/controller/initializationSpec.cfc
Paths without a separator resolve against filePath; paths with a separator pass through to cfmailparam unchanged vendor/wheels/controller/miscellaneous.cfc:152if (!ReFindNoCase("\|/", local.item)) prepends ExpandPath($get("filePath")) & "/", else no transformation
filePath default is files, expanding under the web root (public/files/ in the v4 template) vendor/wheels/events/init/views.cfm:13application.$wheels.filePath = "files"; and public/files/ exists in the repo's app template

The reworded SMTP-spooling paragraph matches standard cfmail behavior on both Lucee and Adobe (spool-by-default), and the push-to-a-job advice is correctly preserved.

Docs

  • Minor, non-blocking: the guide's new centerpiece is the controller() factory, but its API docstring says "Used primarily for testing purposes" (vendor/wheels/Global.cfc:1201). A reader cross-referencing the API reference may hesitate at recommending a "testing" helper for production mailers. Since #3078 (cited in the new Aside) tracks the proper out-of-request sendEmail() hardening, consider either softening that docstring in a follow-up or adding half a sentence in the guide noting this is the supported interim pattern until #3078 lands. No change required to merge.

Commits

docs(web/guides): fix sending-email guide mailer pattern, attachment paths, and SMTP wording — valid type, header 94 chars, DCO sign-off present and matching the author. PR title is also a valid conventional-commit header (96 chars). No findings.

Tests

Docs-only change; the PR retains the {test:compile} annotations on every modified code block and reports pnpm verify:docs passing 11/11 on the page. No framework spec needed. No changelog fragment needed (docs type, not a user-facing fix/feat).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant