workerman 定时器中的任务执行失败了,怎么做异常处理?

0

我使用了thinkphp5.0在id=0的进程上创建了一个查询数据的邮件内容,定时发送邮件的任务.


worker.php如下:


namespace app\push\controller;

use think\worker\Server;

use Workerman\Lib\Timer;
use think\Log;

class Worker extends Server
{
protected $socket = 'websocket://0.0.0.0:2344';

/**
* 收到信息
* @param $connection
* @param $data
*/
public function onMessage($connection, $data)
{
}

/**
* 当连接建立时触发的回调函数
* @param $connection
*/
public function onConnect($connection)
{
}

/**
* 当连接断开时触发的回调函数
* @param $connection
*/
public function onClose($connection)
{
}

/**
* 当客户端的连接上发生错误时触发
* @param $connection
* @param $code
* @param $msg
*/
public function onError($connection, $code, $msg)
{
}

/**
* 每个进程启动
* @param $worker
*/
public function onWorkerStart($worker)
{

// 只在id编号为0的进程上设置定时器,其它1、2、3号进程不设置定时器
if($worker->id === 0) {
Timer::add(2, function()use($worker){
Log::record('[Worker][id][1][SendMail]');
$watcher = controller('tasks/MailMan');
$watcher->dog();
});
}
}
}

task/MailMan执行的任务内容如下:


namespace app\tasks\controller;

use ext\MailTemplate;
use think\Db;
use think\Exception;
use think\Loader;
use think\Log;
Loader::import('lib.swift_required');
use Swift_SmtpTransport;
use Swift_Mailer;
use Swift_Message;

class MailMan {

public function dog() {

try {
Log::record('[MailMan] start');

$res = Db::table('ems_mail_queue')->where('to', '<>', '[]')
->order('id')->select();

foreach ($res as $key => $item) {
if (FLOW == $item['type']) {
$content = MailTemplate::getContent($item['main_body'], $item['table_data']);
$cc = config('mail_cc');
} else {
$content = MailTemplate::getImportContent($item['main_body'], $item['table_data']);
$cc = config('mail_import_cc');
}

Log::record($content);
$r = self::send($item['from'], json_decode($item['to'], true), $cc,
$item['subject'], $content);

if ($r > 0) {
Log::record('[MailMan][dog] success ' .$item['id']);

// 删除该条记录
Db::table('ems_mail_queue')->where('id', $item['id'])->delete();

} else {
Log::record('[MailMan][dog] fail ' .$item['id']);
}

}
} catch (Exception $e) {
Log::record('[MailMan][dog] error' . $e->getMessage());
}

Log::record('[MailMan] end');
}

// 发送邮件function
private static function send($from, $to, $cc, $mailTitle, $content) {

$transport = Swift_SmtpTransport::newInstance(config('smtp_host'), config('smtp_port'));

$mailer = Swift_Mailer::newInstance($transport);

// Create a message
$message = Swift_Message::newInstance($mailTitle)
->setFrom(array($from))
->setTo($to) // 这里也是需要数组的
->setCc(json_decode($cc, true))
->setBody($content, 'text/html', 'utf-8');

// Send the message
$result = $mailer->send($message);
return $result;
}
}

我碰到的是如果MailMan.php中的$item['from']或者$item['to']的数据不对,也就是发件人或者收件人的地址不对,导致邮件发送不出去报错了.怎么才能控制异常,执行$res下一条数据?


如下图.我启动的server.php执行的时候像是碰到了异常,会终止该进程号重新开启一个新的workman进程号?


php server.php start执行中的错误

error.png
已邀请:

张先生

赞同来自:

自己捕获异常呀,把异常处理掉,也可以验证一下你的邮箱地址。

ss7424

赞同来自:

我改掉邮件发送异常捕捉的方式了.


try {
$r = self::send($item['from'], json_decode($item['to'], true), $cc,
$item['subject'], $content);

if ($r > 0) {
Log::record('[MailMan][dog] success ' .$item['id']);

// 删除该条记录
Db::table('ems_mail_queue')->where('id', $item['id'])->delete();
}
} catch (Swift_RfcComplianceException $e) {
Log::record('[MailMan][dog] fail ' .$item['id'] .' '.$e->getMessage());
}

要回复问题请先登录注册