UrsRelationCacheLogic.php 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590
  1. <?php
  2. namespace App\Module\UrsPromotion\Logics;
  3. use App\Module\UrsPromotion\Enums\UrsPromotionRelationLevel;
  4. use App\Module\UrsPromotion\Models\UrsUserReferral;
  5. use App\Module\UrsPromotion\Models\UrsUserRelationCache;
  6. use App\Module\UrsPromotion\Services\UrsUserMappingService;
  7. use Illuminate\Support\Facades\DB;
  8. use Illuminate\Support\Facades\Log;
  9. use Illuminate\Support\Facades\Redis;
  10. /**
  11. * URS关系缓存逻辑类
  12. *
  13. * 处理URS用户关系缓存的核心业务逻辑,包括生成关系缓存、清理关系缓存、
  14. * 重建关系缓存等功能。该类仅供内部使用,不对外提供服务。
  15. */
  16. class UrsRelationCacheLogic
  17. {
  18. /**
  19. * 生成用户的关系缓存
  20. *
  21. * @param int $ursUserId URS用户ID
  22. * @return bool
  23. */
  24. public function generateUserRelationCache(int $ursUserId): bool
  25. {
  26. try {
  27. // 清除用户的现有关系缓存
  28. $this->clearUserRelationCache($ursUserId);
  29. // 获取用户的直接推荐人
  30. $referral = UrsUserReferral::where('urs_user_id', $ursUserId)
  31. ->where('status', UrsUserReferral::STATUS_VALID)
  32. ->first();
  33. if (!$referral) {
  34. Log::info("URS用户 {$ursUserId} 没有推荐人,无需生成关系缓存");
  35. return true;
  36. }
  37. $ursReferrerId = $referral->urs_referrer_id;
  38. // 获取农场用户ID
  39. $farmUserId = UrsUserMappingService::getFarmUserId($ursUserId);
  40. $farmReferrerId = UrsUserMappingService::getFarmUserId($ursReferrerId);
  41. // 如果当前用户未进入农场,无法生成缓存
  42. if ($farmUserId <= 0) {
  43. Log::info("URS用户 {$ursUserId} 未进入农场,跳过缓存生成");
  44. return true;
  45. }
  46. // 如果推荐人未进入农场,创建占位缓存记录,避免断代问题
  47. if ($farmReferrerId <= 0) {
  48. Log::info("URS用户 {$ursUserId} 的推荐人 {$ursReferrerId} 未进入农场,创建占位缓存记录");
  49. // 检查是否已存在该深度的缓存记录,避免重复插入
  50. $existingCache = UrsUserRelationCache::where('urs_user_id', $ursUserId)
  51. ->where('urs_related_user_id', $ursReferrerId)
  52. ->where('depth', 1)
  53. ->first();
  54. if (!$existingCache) {
  55. // 创建占位的直接关系缓存(农场用户ID为0)
  56. $directRelation = new UrsUserRelationCache();
  57. $directRelation->user_id = $farmUserId;
  58. $directRelation->related_user_id = 0; // 推荐人未进入农场,设为0
  59. $directRelation->urs_user_id = $ursUserId;
  60. $directRelation->urs_related_user_id = $ursReferrerId;
  61. $directRelation->level = UrsPromotionRelationLevel::DIRECT;
  62. $directRelation->path = '0'; // 占位路径
  63. $directRelation->urs_path = (string)$ursReferrerId;
  64. $directRelation->depth = 1;
  65. $directRelation->save();
  66. } else {
  67. Log::debug("URS用户 {$ursUserId} 的占位缓存记录已存在,跳过创建");
  68. }
  69. // 尝试获取推荐人的上级关系(基于URS关系)
  70. $this->generateIndirectRelationsFromUrsChain($ursUserId, $farmUserId, $ursReferrerId, 1, (string)$ursReferrerId, '0');
  71. Log::info("URS用户 {$ursUserId} 占位缓存记录创建完成");
  72. return true;
  73. }
  74. // 创建直接关系缓存
  75. $directRelation = new UrsUserRelationCache();
  76. $directRelation->user_id = $farmUserId;
  77. $directRelation->related_user_id = $farmReferrerId;
  78. $directRelation->urs_user_id = $ursUserId;
  79. $directRelation->urs_related_user_id = $ursReferrerId;
  80. $directRelation->level = UrsPromotionRelationLevel::DIRECT;
  81. $directRelation->path = (string)$farmReferrerId;
  82. $directRelation->urs_path = (string)$ursReferrerId;
  83. $directRelation->depth = 1;
  84. $directRelation->save();
  85. // 基于URS推荐关系链直接生成所有间接关系(不依赖缓存)
  86. $this->generateIndirectRelationsFromUrsChain($ursUserId, $farmUserId, $ursReferrerId, 1, (string)$ursReferrerId, (string)$farmReferrerId);
  87. // 清除Redis缓存
  88. Redis::del("urs_promotion:user:{$ursUserId}:all_referrers");
  89. Redis::del("urs_promotion:farm_user:{$farmUserId}:all_referrers");
  90. Log::info("URS用户 {$ursUserId} 关系缓存生成成功");
  91. return true;
  92. } catch (\Exception $e) {
  93. Log::error("生成URS用户关系缓存失败", [
  94. 'urs_user_id' => $ursUserId,
  95. 'error' => $e->getMessage()
  96. ]);
  97. return false;
  98. }
  99. }
  100. /**
  101. * 基于URS关系链生成间接关系缓存
  102. *
  103. * 当推荐人未进入农场时,通过URS推荐关系链向上查找已进入农场的上级
  104. *
  105. * @param int $ursUserId 当前用户的URS用户ID
  106. * @param int $farmUserId 当前用户的农场用户ID
  107. * @param int $currentUrsReferrerId 当前层级的URS推荐人ID
  108. * @param int $currentDepth 当前深度
  109. * @param string $currentUrsPath 当前URS路径链
  110. * @param string $currentFarmPath 当前农场路径链
  111. * @return void
  112. */
  113. private function generateIndirectRelationsFromUrsChain(int $ursUserId, int $farmUserId, int $currentUrsReferrerId, int $currentDepth, string $currentUrsPath = '', string $currentFarmPath = ''): void
  114. {
  115. // 限制最大深度为20代
  116. if ($currentDepth >= UrsPromotionRelationLevel::getMaxLevel()) {
  117. return;
  118. }
  119. // 获取当前推荐人的推荐人
  120. $upperReferral = UrsUserReferral::where('urs_user_id', $currentUrsReferrerId)
  121. ->where('status', UrsUserReferral::STATUS_VALID)
  122. ->first();
  123. if (!$upperReferral) {
  124. // 没有更上级的推荐人,结束递归
  125. return;
  126. }
  127. $upperUrsReferrerId = $upperReferral->urs_referrer_id;
  128. $upperFarmReferrerId = UrsUserMappingService::getFarmUserId($upperUrsReferrerId);
  129. $newDepth = $currentDepth + 1;
  130. // 构建新的路径链
  131. $newUrsPath = empty($currentUrsPath) ? (string)$upperUrsReferrerId : $currentUrsPath . ',' . $upperUrsReferrerId;
  132. $currentFarmReferrerId = UrsUserMappingService::getFarmUserId($currentUrsReferrerId);
  133. $currentFarmPart = $currentFarmReferrerId > 0 ? (string)$currentFarmReferrerId : '0';
  134. $upperFarmPart = $upperFarmReferrerId > 0 ? (string)$upperFarmReferrerId : '0';
  135. $newFarmPath = empty($currentFarmPath) ? $upperFarmPart : $currentFarmPath . ',' . $upperFarmPart;
  136. if ($upperFarmReferrerId > 0) {
  137. // 检查是否已存在该深度的关系缓存
  138. $existingCache = UrsUserRelationCache::where('urs_user_id', $ursUserId)
  139. ->where('urs_related_user_id', $upperUrsReferrerId)
  140. ->where('depth', $newDepth)
  141. ->first();
  142. if (!$existingCache) {
  143. // 上级推荐人已进入农场,创建有效的关系缓存
  144. $indirectRelation = new UrsUserRelationCache();
  145. $indirectRelation->user_id = $farmUserId;
  146. $indirectRelation->related_user_id = $upperFarmReferrerId;
  147. $indirectRelation->urs_user_id = $ursUserId;
  148. $indirectRelation->urs_related_user_id = $upperUrsReferrerId;
  149. $indirectRelation->level = UrsPromotionRelationLevel::getLevelByDepth($newDepth);
  150. $indirectRelation->path = $newFarmPath;
  151. $indirectRelation->urs_path = $newUrsPath;
  152. $indirectRelation->depth = $newDepth;
  153. $indirectRelation->save();
  154. }
  155. Log::debug("为URS用户 {$ursUserId} 创建间接关系缓存", [
  156. 'upper_urs_referrer_id' => $upperUrsReferrerId,
  157. 'upper_farm_referrer_id' => $upperFarmReferrerId,
  158. 'depth' => $newDepth
  159. ]);
  160. // 继续向上递归查找,基于URS推荐关系链
  161. $this->generateIndirectRelationsFromUrsChain($ursUserId, $farmUserId, $upperUrsReferrerId, $newDepth, $newUrsPath, $newFarmPath);
  162. } else {
  163. // 检查是否已存在该深度的占位缓存
  164. $existingCache = UrsUserRelationCache::where('urs_user_id', $ursUserId)
  165. ->where('urs_related_user_id', $upperUrsReferrerId)
  166. ->where('depth', $newDepth)
  167. ->first();
  168. if (!$existingCache) {
  169. // 上级推荐人也未进入农场,创建占位缓存并继续向上查找
  170. $indirectRelation = new UrsUserRelationCache();
  171. $indirectRelation->user_id = $farmUserId;
  172. $indirectRelation->related_user_id = 0; // 占位
  173. $indirectRelation->urs_user_id = $ursUserId;
  174. $indirectRelation->urs_related_user_id = $upperUrsReferrerId;
  175. $indirectRelation->level = UrsPromotionRelationLevel::getLevelByDepth($newDepth);
  176. $indirectRelation->path = $newFarmPath;
  177. $indirectRelation->urs_path = $newUrsPath;
  178. $indirectRelation->depth = $newDepth;
  179. $indirectRelation->save();
  180. }
  181. // 继续向上递归查找
  182. $this->generateIndirectRelationsFromUrsChain($ursUserId, $farmUserId, $upperUrsReferrerId, $newDepth, $newUrsPath, $newFarmPath);
  183. }
  184. }
  185. /**
  186. * 清除用户的关系缓存
  187. *
  188. * @param int $ursUserId URS用户ID
  189. * @return bool
  190. */
  191. public function clearUserRelationCache(int $ursUserId): bool
  192. {
  193. try {
  194. // 获取农场用户ID
  195. $farmUserId = UrsUserMappingService::getFarmUserId($ursUserId);
  196. // 删除数据库中的关系缓存
  197. UrsUserRelationCache::where('urs_user_id', $ursUserId)->delete();
  198. // 清除Redis缓存
  199. Redis::del("urs_promotion:user:{$ursUserId}:all_referrers");
  200. if ($farmUserId > 0) {
  201. Redis::del("urs_promotion:farm_user:{$farmUserId}:all_referrers");
  202. }
  203. return true;
  204. } catch (\Exception $e) {
  205. Log::error("清除URS用户关系缓存失败", [
  206. 'urs_user_id' => $ursUserId,
  207. 'error' => $e->getMessage()
  208. ]);
  209. return false;
  210. }
  211. }
  212. /**
  213. * 重建所有用户的关系缓存
  214. *
  215. * @param int $batchSize 批处理大小
  216. * @param callable|null $progressCallback 进度回调函数
  217. * @return array 包含成功和失败的数量
  218. */
  219. public function rebuildAllRelationCache(int $batchSize = 100, ?callable $progressCallback = null): array
  220. {
  221. try {
  222. // 清空关系缓存表
  223. UrsUserRelationCache::truncate();
  224. // 清除所有Redis缓存
  225. $keys = Redis::keys("urs_promotion:user:*:all_referrers");
  226. if (!empty($keys)) {
  227. Redis::del($keys);
  228. }
  229. $keys = Redis::keys("urs_promotion:farm_user:*:all_referrers");
  230. if (!empty($keys)) {
  231. Redis::del($keys);
  232. }
  233. // 获取所有URS用户ID
  234. $ursUserIds = UrsUserReferral::where('status', UrsUserReferral::STATUS_VALID)
  235. ->pluck('urs_user_id')
  236. ->toArray();
  237. $successCount = 0;
  238. $failCount = 0;
  239. $totalUsers = count($ursUserIds);
  240. $processedCount = 0;
  241. // 分批处理
  242. $chunks = array_chunk($ursUserIds, $batchSize);
  243. foreach ($chunks as $chunk) {
  244. foreach ($chunk as $ursUserId) {
  245. $processedCount++;
  246. // 调用进度回调函数
  247. if ($progressCallback) {
  248. $progressCallback($ursUserId, $processedCount, $totalUsers, $successCount, $failCount);
  249. }
  250. if ($this->generateUserRelationCache($ursUserId)) {
  251. $successCount++;
  252. } else {
  253. $failCount++;
  254. }
  255. }
  256. }
  257. Log::info("URS关系缓存重建完成", [
  258. 'success' => $successCount,
  259. 'fail' => $failCount,
  260. 'total' => count($ursUserIds)
  261. ]);
  262. return [
  263. 'success' => $successCount,
  264. 'fail' => $failCount,
  265. 'total' => count($ursUserIds)
  266. ];
  267. } catch (\Exception $e) {
  268. Log::error("重建所有URS关系缓存失败: " . $e->getMessage());
  269. return [
  270. 'success' => 0,
  271. 'fail' => 0,
  272. 'total' => 0,
  273. 'error' => $e->getMessage()
  274. ];
  275. }
  276. }
  277. /**
  278. * 检查关系缓存的完整性
  279. *
  280. * @return array 包含检查结果
  281. */
  282. public function checkRelationCacheIntegrity(): array
  283. {
  284. try {
  285. $totalUsers = UrsUserReferral::where('status', UrsUserReferral::STATUS_VALID)->count();
  286. $usersWithCache = UrsUserRelationCache::distinct('urs_user_id')->count('urs_user_id');
  287. $missingUsers = $totalUsers - $usersWithCache;
  288. // 检查循环推荐关系
  289. $circularRelations = DB::select("
  290. SELECT r1.urs_user_id, r1.urs_referrer_id
  291. FROM kku_urs_promotion_user_referrals r1
  292. JOIN kku_urs_promotion_user_referrals r2 ON r1.urs_referrer_id = r2.urs_user_id
  293. WHERE r2.urs_referrer_id = r1.urs_user_id
  294. AND r1.status = 1 AND r2.status = 1
  295. ");
  296. // 检查孤立的缓存
  297. $orphanedCaches = DB::select("
  298. SELECT c.urs_user_id
  299. FROM kku_urs_promotion_user_relation_cache c
  300. LEFT JOIN kku_urs_promotion_user_referrals r ON c.urs_user_id = r.urs_user_id AND r.status = 1
  301. WHERE r.urs_user_id IS NULL
  302. ");
  303. return [
  304. 'total_users' => $totalUsers,
  305. 'users_with_cache' => $usersWithCache,
  306. 'missing_users' => $missingUsers,
  307. 'circular_relations' => count($circularRelations),
  308. 'orphaned_caches' => count($orphanedCaches)
  309. ];
  310. } catch (\Exception $e) {
  311. Log::error("检查URS关系缓存完整性失败: " . $e->getMessage());
  312. return [
  313. 'error' => $e->getMessage()
  314. ];
  315. }
  316. }
  317. /**
  318. * 修复关系缓存问题
  319. *
  320. * @param callable|null $progressCallback 进度回调函数
  321. * @return array 包含修复结果
  322. */
  323. public function fixRelationCacheIssues(?callable $progressCallback = null): array
  324. {
  325. try {
  326. // 检查完整性
  327. $integrity = $this->checkRelationCacheIntegrity();
  328. $fixed = [
  329. 'missing_users' => 0,
  330. 'orphaned_caches' => 0
  331. ];
  332. // 修复缺失的用户缓存
  333. if ($integrity['missing_users'] > 0) {
  334. $usersWithCache = UrsUserRelationCache::distinct('urs_user_id')->pluck('urs_user_id')->toArray();
  335. $allUsers = UrsUserReferral::where('status', UrsUserReferral::STATUS_VALID)
  336. ->pluck('urs_user_id')
  337. ->toArray();
  338. $missingUsers = array_diff($allUsers, $usersWithCache);
  339. $totalMissing = count($missingUsers);
  340. $processedMissing = 0;
  341. foreach ($missingUsers as $ursUserId) {
  342. $processedMissing++;
  343. // 调用进度回调函数
  344. if ($progressCallback) {
  345. $progressCallback('missing', $ursUserId, $processedMissing, $totalMissing, $fixed['missing_users']);
  346. }
  347. if ($this->generateUserRelationCache($ursUserId)) {
  348. $fixed['missing_users']++;
  349. }
  350. }
  351. }
  352. // 清理孤立的缓存
  353. if ($integrity['orphaned_caches'] > 0) {
  354. $orphanedCaches = DB::select("
  355. SELECT c.urs_user_id
  356. FROM kku_urs_promotion_user_relation_cache c
  357. LEFT JOIN kku_urs_promotion_user_referrals r ON c.urs_user_id = r.urs_user_id AND r.status = 1
  358. WHERE r.urs_user_id IS NULL
  359. ");
  360. $totalOrphaned = count($orphanedCaches);
  361. $processedOrphaned = 0;
  362. foreach ($orphanedCaches as $cache) {
  363. $processedOrphaned++;
  364. // 调用进度回调函数
  365. if ($progressCallback) {
  366. $progressCallback('orphaned', $cache->urs_user_id, $processedOrphaned, $totalOrphaned, $fixed['orphaned_caches']);
  367. }
  368. if ($this->clearUserRelationCache($cache->urs_user_id)) {
  369. $fixed['orphaned_caches']++;
  370. }
  371. }
  372. }
  373. return [
  374. 'integrity' => $integrity,
  375. 'fixed' => $fixed
  376. ];
  377. } catch (\Exception $e) {
  378. Log::error("修复URS关系缓存问题失败: " . $e->getMessage());
  379. return [
  380. 'error' => $e->getMessage()
  381. ];
  382. }
  383. }
  384. /**
  385. * 为特定用户更新农场用户ID相关的缓存
  386. *
  387. * @param int $ursUserId URS用户ID
  388. * @param int $farmUserId 农场用户ID
  389. * @return bool
  390. */
  391. public function updateFarmUserIdInCache(int $ursUserId, int $farmUserId): bool
  392. {
  393. try {
  394. // 更新该用户作为被推荐人的缓存记录
  395. UrsUserRelationCache::where('urs_user_id', $ursUserId)
  396. ->update(['user_id' => $farmUserId]);
  397. // 更新该用户作为推荐人的缓存记录(将占位的0更新为实际农场用户ID)
  398. $updatedCount = UrsUserRelationCache::where('urs_related_user_id', $ursUserId)
  399. ->where('related_user_id', 0) // 只更新占位记录
  400. ->update(['related_user_id' => $farmUserId]);
  401. if ($updatedCount > 0) {
  402. Log::info("更新了 {$updatedCount} 条占位缓存记录", [
  403. 'urs_user_id' => $ursUserId,
  404. 'farm_user_id' => $farmUserId
  405. ]);
  406. // 更新路径中的占位符
  407. $this->updatePlaceholderPaths($ursUserId, $farmUserId);
  408. }
  409. // 重新生成该用户的关系缓存(确保路径正确)
  410. $this->generateUserRelationCache($ursUserId);
  411. // 为该用户的所有下级重新生成缓存(修复断代问题)
  412. $this->regenerateDownstreamCaches($ursUserId);
  413. Log::info("URS用户关系缓存中的农场用户ID更新成功", [
  414. 'urs_user_id' => $ursUserId,
  415. 'farm_user_id' => $farmUserId,
  416. 'updated_placeholder_count' => $updatedCount
  417. ]);
  418. return true;
  419. } catch (\Exception $e) {
  420. Log::error("更新URS用户关系缓存中的农场用户ID失败", [
  421. 'urs_user_id' => $ursUserId,
  422. 'farm_user_id' => $farmUserId,
  423. 'error' => $e->getMessage()
  424. ]);
  425. return false;
  426. }
  427. }
  428. /**
  429. * 更新路径中的占位符
  430. *
  431. * @param int $ursUserId URS用户ID
  432. * @param int $farmUserId 农场用户ID
  433. * @return void
  434. */
  435. private function updatePlaceholderPaths(int $ursUserId, int $farmUserId): void
  436. {
  437. try {
  438. // 获取所有包含该用户的路径记录
  439. $records = UrsUserRelationCache::where('urs_path', 'LIKE', "%{$ursUserId}%")->get();
  440. foreach ($records as $record) {
  441. $pathParts = explode(',', $record->path);
  442. $ursPathParts = explode(',', $record->urs_path);
  443. // 找到URS路径中对应的位置,更新农场用户路径
  444. $ursIndex = array_search((string)$ursUserId, $ursPathParts);
  445. if ($ursIndex !== false && isset($pathParts[$ursIndex]) && $pathParts[$ursIndex] === '0') {
  446. $pathParts[$ursIndex] = (string)$farmUserId;
  447. $record->path = implode(',', $pathParts);
  448. $record->save();
  449. }
  450. }
  451. Log::debug("更新路径占位符完成", [
  452. 'urs_user_id' => $ursUserId,
  453. 'farm_user_id' => $farmUserId,
  454. 'updated_records' => $records->count()
  455. ]);
  456. } catch (\Exception $e) {
  457. Log::warning("更新路径占位符失败", [
  458. 'urs_user_id' => $ursUserId,
  459. 'farm_user_id' => $farmUserId,
  460. 'error' => $e->getMessage()
  461. ]);
  462. }
  463. }
  464. /**
  465. * 为用户的所有下级重新生成缓存
  466. *
  467. * 当用户进入农场后,需要为其所有下级重新生成缓存以修复断代问题
  468. *
  469. * @param int $ursUserId URS用户ID
  470. * @return void
  471. */
  472. private function regenerateDownstreamCaches(int $ursUserId): void
  473. {
  474. try {
  475. // 获取该用户的所有直接下级
  476. $directSubordinates = UrsUserReferral::where('urs_referrer_id', $ursUserId)
  477. ->where('status', UrsUserReferral::STATUS_VALID)
  478. ->pluck('urs_user_id')
  479. ->toArray();
  480. if (empty($directSubordinates)) {
  481. return;
  482. }
  483. Log::info("开始为用户的下级重新生成缓存", [
  484. 'urs_user_id' => $ursUserId,
  485. 'subordinate_count' => count($directSubordinates)
  486. ]);
  487. foreach ($directSubordinates as $subordinateUrsUserId) {
  488. // 检查下级是否已进入农场
  489. $subordinateFarmUserId = UrsUserMappingService::getFarmUserId($subordinateUrsUserId);
  490. if ($subordinateFarmUserId > 0) {
  491. // 重新生成下级的关系缓存
  492. $this->generateUserRelationCache($subordinateUrsUserId);
  493. // 递归处理下级的下级
  494. $this->regenerateDownstreamCaches($subordinateUrsUserId);
  495. }
  496. }
  497. Log::info("用户下级缓存重新生成完成", [
  498. 'urs_user_id' => $ursUserId
  499. ]);
  500. } catch (\Exception $e) {
  501. Log::error("重新生成下级缓存失败", [
  502. 'urs_user_id' => $ursUserId,
  503. 'error' => $e->getMessage()
  504. ]);
  505. }
  506. }
  507. }