From b4a10160365aa9bb19469f07b016183e84b0d045 Mon Sep 17 00:00:00 2001 From: Yurii Date: Wed, 25 Mar 2026 16:23:10 +0200 Subject: [PATCH] formula function errors instead of log messages --- .../DatetimeGroup/AddIntervalType.php | 18 ++++--- .../ExtGroup/EmailGroup/ApplyTemplateType.php | 27 +++++----- .../ExtGroup/EmailGroup/SendType.php | 49 ++++++++----------- .../ExtGroup/PdfGroup/GenerateType.php | 21 ++------ .../Functions/ExtGroup/SmsGroup/SendType.php | 25 ++++------ .../ExtGroup/UserGroup/SendAccessInfoType.php | 15 +++--- application/Espo/Entities/Email.php | 1 + 7 files changed, 65 insertions(+), 91 deletions(-) diff --git a/application/Espo/Core/Formula/Functions/DatetimeGroup/AddIntervalType.php b/application/Espo/Core/Formula/Functions/DatetimeGroup/AddIntervalType.php index 08259d0cd0..a271fa4734 100644 --- a/application/Espo/Core/Formula/Functions/DatetimeGroup/AddIntervalType.php +++ b/application/Espo/Core/Formula/Functions/DatetimeGroup/AddIntervalType.php @@ -30,12 +30,12 @@ namespace Espo\Core\Formula\Functions\DatetimeGroup; use Espo\Core\Di; +use Espo\Core\Formula\Exceptions\FunctionRuntimeError; use Espo\Core\Utils\DateTime as DateTimeUtil; - use Espo\Core\Formula\ArgumentList; use Espo\Core\Formula\Functions\BaseFunction; - use DateTime; +use DateMalformedStringException; use Exception; abstract class AddIntervalType extends BaseFunction implements Di\DateTimeAware @@ -82,14 +82,16 @@ abstract class AddIntervalType extends BaseFunction implements Di\DateTimeAware try { $dateTime = new DateTime($dateTimeString); } catch (Exception) { - $this->log('bad date-time value passed', 'warning'); - - return null; + throw new FunctionRuntimeError("Bad date-time value '$dateTimeString'."); } - $dateTime->modify( - ($interval > 0 ? '+' : '') . strval($interval) . ' ' . $this->intervalTypeString - ); + $modifier = ($interval > 0 ? '+' : '') . $interval . ' ' . $this->intervalTypeString; + + try { + $dateTime->modify($modifier); + } catch (DateMalformedStringException $e) { + throw new FunctionRuntimeError($e->getMessage(), previous: $e); + } if ($isTime) { return $dateTime->format(DateTimeUtil::SYSTEM_DATE_TIME_FORMAT); diff --git a/application/Espo/Core/Formula/Functions/ExtGroup/EmailGroup/ApplyTemplateType.php b/application/Espo/Core/Formula/Functions/ExtGroup/EmailGroup/ApplyTemplateType.php index e2d42055b9..007d594753 100644 --- a/application/Espo/Core/Formula/Functions/ExtGroup/EmailGroup/ApplyTemplateType.php +++ b/application/Espo/Core/Formula/Functions/ExtGroup/EmailGroup/ApplyTemplateType.php @@ -29,6 +29,8 @@ namespace Espo\Core\Formula\Functions\ExtGroup\EmailGroup; +use Espo\Core\Formula\Exceptions\FunctionRuntimeError; +use Espo\Core\ORM\Repository\Option\SaveOption; use Espo\Core\Utils\SystemUser; use Espo\Entities\Email; use Espo\Core\Formula\ArgumentList; @@ -39,6 +41,9 @@ use Espo\Tools\EmailTemplate\Data; use Espo\Tools\EmailTemplate\Params; use Espo\Tools\EmailTemplate\Processor; +/** + * @noinspection PhpUnused + */ class ApplyTemplateType extends BaseFunction implements Di\EntityManagerAware, @@ -78,35 +83,27 @@ class ApplyTemplateType extends BaseFunction implements $em = $this->entityManager; - /** @var ?Email $email */ - $email = $em->getEntityById(Email::ENTITY_TYPE, $id); - /** @var ?EmailTemplate $emailTemplate */ - $emailTemplate = $em->getEntityById(EmailTemplate::ENTITY_TYPE, $templateId); + $email = $em->getRDBRepositoryByClass(Email::class)->getById($id); + $emailTemplate = $em->getRDBRepositoryByClass(EmailTemplate::class)->getById($templateId); if (!$email) { - $this->log("Email {$id} does not exist."); - - return false; + throw new FunctionRuntimeError("Email $id does not exist."); } if (!$emailTemplate) { - $this->log("EmailTemplate {$templateId} does not exist."); - - return false; + throw new FunctionRuntimeError("EmailTemplate $templateId does not exist."); } $status = $email->getStatus(); if ($status && $status === Email::STATUS_SENT) { - $this->log("Can't apply template to email with 'Sent' status."); - - return false; + throw new FunctionRuntimeError("Can't apply template to email with 'Sent' status."); } $processor = $this->injectableFactory->create(Processor::class); $params = Params::create() - ->withCopyAttachments(true) + ->withCopyAttachments() ->withApplyAcl(false); $data = Data::create(); @@ -144,7 +141,7 @@ class ApplyTemplateType extends BaseFunction implements $systemUserId = $this->injectableFactory->create(SystemUser::class)->getId(); $em->saveEntity($email, [ - 'modifiedById' => $systemUserId, + SaveOption::MODIFIED_BY_ID => $systemUserId, ]); return true; diff --git a/application/Espo/Core/Formula/Functions/ExtGroup/EmailGroup/SendType.php b/application/Espo/Core/Formula/Functions/ExtGroup/EmailGroup/SendType.php index b5b5104241..6137310285 100644 --- a/application/Espo/Core/Formula/Functions/ExtGroup/EmailGroup/SendType.php +++ b/application/Espo/Core/Formula/Functions/ExtGroup/EmailGroup/SendType.php @@ -29,7 +29,7 @@ namespace Espo\Core\Formula\Functions\ExtGroup\EmailGroup; -use Espo\Core\ApplicationUser; +use Espo\Core\Formula\Exceptions\FunctionRuntimeError; use Espo\Core\Mail\ConfigDataProvider; use Espo\Core\ORM\Repository\Option\SaveOption; use Espo\Core\Formula\ArgumentList; @@ -37,21 +37,22 @@ use Espo\Core\Formula\Functions\BaseFunction; use Espo\Core\Utils\SystemUser; use Espo\Entities\Email; use Espo\Tools\Email\SendService; - use Espo\Core\Di; - use Exception; +/** + * @noinspection PhpUnused + */ class SendType extends BaseFunction implements Di\EntityManagerAware, - Di\ServiceFactoryAware, Di\ConfigAware, - Di\InjectableFactoryAware + Di\InjectableFactoryAware, + Di\RecordServiceContainerAware { use Di\EntityManagerSetter; - use Di\ServiceFactorySetter; use Di\ConfigSetter; use Di\InjectableFactorySetter; + use Di\RecordServiceContainerSetter; public function process(ArgumentList $args) { @@ -69,43 +70,35 @@ class SendType extends BaseFunction implements $em = $this->entityManager; - /** @var ?Email $email */ - $email = $em->getEntityById(Email::ENTITY_TYPE, $id); + $email = $em->getRDBRepositoryByClass(Email::class)->getById($id); if (!$email) { - $this->log("Email '{$id}' does not exist."); - - return false; + throw new FunctionRuntimeError("Email $id does not exist."); } - $status = $email->getStatus(); - - if ($status === Email::STATUS_SENT) { - $this->log("Can't send email that has 'Sent' status."); - - return false; + if ($email->getStatus() === Email::STATUS_SENT) { + throw new FunctionRuntimeError("Can't send email that has 'Sent' status."); } - /** @var \Espo\Services\Email $service */ - $service = $this->serviceFactory->create(Email::ENTITY_TYPE); - - $service->loadAdditionalFields($email); + $this->recordServiceContainer + ->getByClass(Email::class) + ->loadAdditionalFields($email); $toSave = false; - if ($status !== Email::STATUS_SENDING) { - $email->set('status', Email::STATUS_SENDING); + if ($email->getStatus() !== Email::STATUS_SENDING) { + $email->setStatus(Email::STATUS_SENDING); $toSave = true; } - if (!$email->get('from')) { + if (!$email->getFromAddress()) { $from = $this->injectableFactory ->create(ConfigDataProvider::class) ->getSystemOutboundAddress(); if ($from) { - $email->set('from', $from); + $email->setFromAddress($from); $toSave = true; } @@ -125,10 +118,10 @@ class SendType extends BaseFunction implements try { $sendService->send($email); } catch (Exception $e) { - $message = $e->getMessage(); - $this->log("Error while sending. Message: {$message}." , 'error'); + $email->setStatus(Email::STATUS_FAILED); + $em->saveEntity($email); - return false; + throw new FunctionRuntimeError("Error while sending email. {$e->getMessage()}", previous: $e); } return true; diff --git a/application/Espo/Core/Formula/Functions/ExtGroup/PdfGroup/GenerateType.php b/application/Espo/Core/Formula/Functions/ExtGroup/PdfGroup/GenerateType.php index 5845ab0fbf..4264e74d8f 100644 --- a/application/Espo/Core/Formula/Functions/ExtGroup/PdfGroup/GenerateType.php +++ b/application/Espo/Core/Formula/Functions/ExtGroup/PdfGroup/GenerateType.php @@ -30,6 +30,7 @@ namespace Espo\Core\Formula\Functions\ExtGroup\PdfGroup; use Espo\Core\Field\LinkParent; +use Espo\Core\Formula\Exceptions\FunctionRuntimeError; use Espo\Core\Name\Field; use Espo\Entities\Attachment; use Espo\Entities\Template; @@ -87,26 +88,16 @@ class GenerateType extends BaseFunction implements $em = $this->entityManager; - try { - $entity = $em->getEntityById($entityType, $id); - } catch (Exception $e) { - $this->log("Message: " . $e->getMessage() . "."); - - throw new Error(); - } + $entity = $em->getEntityById($entityType, $id); if (!$entity) { - $this->log("Record $entityType $id does not exist."); - - throw new Error(); + throw new FunctionRuntimeError("Record $entityType $id does not exist."); } $template = $em->getRDBRepositoryByClass(Template::class)->getById($templateId); if (!$template) { - $this->log("Template $templateId does not exist."); - - throw new Error(); + throw new FunctionRuntimeError("Template $templateId does not exist."); } $params = Params::create()->withAcl(false); @@ -121,9 +112,7 @@ class GenerateType extends BaseFunction implements params: $params, ); } catch (Exception $e) { - $this->log("Error while generating. Message: " . $e->getMessage() . ".", 'error'); - - throw new Error(); + throw new FunctionRuntimeError("Error while generating PDF template. {$e->getMessage()}", previous: $e); } $fileName = $this->prepareFilename($fileName, $result, $entity); diff --git a/application/Espo/Core/Formula/Functions/ExtGroup/SmsGroup/SendType.php b/application/Espo/Core/Formula/Functions/ExtGroup/SmsGroup/SendType.php index b75190877f..86be183126 100644 --- a/application/Espo/Core/Formula/Functions/ExtGroup/SmsGroup/SendType.php +++ b/application/Espo/Core/Formula/Functions/ExtGroup/SmsGroup/SendType.php @@ -29,15 +29,17 @@ namespace Espo\Core\Formula\Functions\ExtGroup\SmsGroup; +use Espo\Core\Formula\Exceptions\FunctionRuntimeError; use Espo\Core\Formula\Functions\BaseFunction; use Espo\Core\Formula\ArgumentList; use Espo\Core\Sms\SmsSender; use Espo\Entities\Sms; - use Espo\Core\Di; - use Exception; +/** + * @noinspection PhpUnused + */ class SendType extends BaseFunction implements Di\EntityManagerAware, @@ -60,19 +62,15 @@ class SendType extends BaseFunction implements $this->throwBadArgumentType(1, 'string'); } - /** @var Sms|null $sms */ - $sms = $this->entityManager->getEntityById(Sms::ENTITY_TYPE, $id); + + $sms = $this->entityManager->getRDBRepositoryByClass(Sms::class)->getById($id); if (!$sms) { - $this->log("Sms '{$id}' does not exist."); - - return false; + throw new FunctionRuntimeError("SMS $id does not exist."); } if ($sms->getStatus() === Sms::STATUS_SENT) { - $this->log("Can't send SMS that has 'Sent' status."); - - return false; + throw new FunctionRuntimeError("Can't send SMS that has 'Sent' status."); } try { @@ -80,15 +78,10 @@ class SendType extends BaseFunction implements $this->entityManager->saveEntity($sms); } catch (Exception $e) { - $message = $e->getMessage(); - - $this->log("Error while sending SMS. Message: {$message}." , 'error'); - $sms->setStatus(Sms::STATUS_FAILED); - $this->entityManager->saveEntity($sms); - return false; + throw new FunctionRuntimeError("Error while sending SMS. {$e->getMessage()}", previous: $e); } return true; diff --git a/application/Espo/Core/Formula/Functions/ExtGroup/UserGroup/SendAccessInfoType.php b/application/Espo/Core/Formula/Functions/ExtGroup/UserGroup/SendAccessInfoType.php index 20a6c7ca7a..991fa18ac0 100644 --- a/application/Espo/Core/Formula/Functions/ExtGroup/UserGroup/SendAccessInfoType.php +++ b/application/Espo/Core/Formula/Functions/ExtGroup/UserGroup/SendAccessInfoType.php @@ -29,19 +29,19 @@ namespace Espo\Core\Formula\Functions\ExtGroup\UserGroup; +use Espo\Core\Formula\Exceptions\FunctionRuntimeError; use Espo\Core\Formula\Functions\BaseFunction; use Espo\Core\Formula\ArgumentList; use Espo\Core\Job\JobSchedulerFactory; - use Espo\Tools\UserSecurity\Password\Jobs\SendAccessInfo as SendAccessInfoJob; use Espo\Core\Job\Job\Data as JobData; - use Espo\Entities\User; - use Espo\Core\Di; +/** + * @noinspection PhpUnused + */ class SendAccessInfoType extends BaseFunction implements - Di\EntityManagerAware, Di\InjectableFactoryAware { @@ -65,16 +65,15 @@ class SendAccessInfoType extends BaseFunction implements $user = $this->entityManager->getEntityById(User::ENTITY_TYPE, $userId); if (!$user) { - $this->log("User '$userId' does not exist."); - - return; + throw new FunctionRuntimeError("User '$userId' does not exist."); } $this->createJobScheduledFactory() ->create() ->setClassName(SendAccessInfoJob::class) ->setData( - JobData::create()->withTargetId($user->getId()) + JobData::create() + ->withTargetId($user->getId()) ) ->schedule(); } diff --git a/application/Espo/Entities/Email.php b/application/Espo/Entities/Email.php index 7fd7315e44..d95bcbc923 100644 --- a/application/Espo/Entities/Email.php +++ b/application/Espo/Entities/Email.php @@ -54,6 +54,7 @@ class Email extends Entity public const STATUS_SENT = 'Sent'; public const STATUS_SENDING = 'Sending'; public const STATUS_DRAFT = 'Draft'; + public const STATUS_FAILED = 'Failed'; public const RELATIONSHIP_EMAIL_USER = 'EmailUser'; public const ALIAS_INBOX = 'emailUserInbox';