PluginProbe ʕ •ᴥ•ʔ
WP STAGING – WordPress Backups, Restore, Migration & Clone / trunk
WP STAGING – WordPress Backups, Restore, Migration & Clone vtrunk
4.11.0 4.10.0 4.9.5 4.9.4 4.9.3 4.9.2 4.9.1 4.9.0 4.8.1 trunk 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.10.0 3.2.0 3.3.1 3.3.2 3.3.3 3.4.1 3.4.3 3.5.0 3.6.0 3.7.1 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.8.6 3.8.7 3.9.0 3.9.1 3.9.2 3.9.3 3.9.4 4.0.0 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.0 4.7.0 4.7.1 4.7.2 4.7.3 4.8.0
wp-staging / Framework / ErrorHandler.php
wp-staging / Framework Last commit date
Adapter 3 days ago Analytics 3 days ago Assets 3 days ago BackgroundProcessing 3 days ago CloningProcess 3 days ago Collection 3 days ago Command 3 days ago Component 3 days ago DI 3 days ago Database 3 days ago DependencyResolver 3 days ago Exceptions 2 years ago Experiments 3 days ago Facades 3 days ago Filesystem 3 days ago Interfaces 3 days ago Job 3 days ago Language 3 days ago Logger 3 days ago Mails 3 days ago Network 3 days ago Newsfeed 3 days ago Notices 3 days ago Onboarding 3 days ago Performance 3 days ago Permalinks 3 days ago Queue 3 days ago Rest 3 days ago Security 3 days ago Settings 3 days ago TemplateEngine 3 days ago ThirdParty 3 days ago Traits 3 days ago Upgrade 3 days ago Utils 3 days ago AnalyticsServiceProvider.php 3 days ago AssetServiceProvider.php 1 year ago CommonServiceProvider.php 3 days ago ErrorHandler.php 3 days ago NoticeServiceProvider.php 1 year ago SettingsServiceProvider.php 4 months ago SiteInfo.php 3 days ago Url.php 3 days ago
ErrorHandler.php
164 lines
1 <?php
2
3 namespace WPStaging\Framework;
4
5 use WPStaging\Core\WPStaging;
6 use WPStaging\Framework\Job\JobTransientCache;
7 use WPStaging\Framework\Job\ProcessLock;
8 use WPStaging\Framework\Logger\SseEventCache;
9
10
11
12
13 class ErrorHandler
14 {
15
16 const ERROR_FILE_EXTENSION = '.wpstgerror';
17
18 public function registerShutdownHandler()
19 {
20 register_shutdown_function([$this, 'shutdownHandler']);
21 }
22
23 public function shutdownHandler()
24 {
25 if (!defined('WPSTG_REQUEST')) {
26 return;
27 }
28
29 if (!defined('WPSTG_UPLOADS_DIR')) {
30 return;
31 }
32
33
34
35
36
37
38 $wpStagingRequests = [
39 'wpstg_backup',
40 'wpstg_restore',
41 'wpstg_cloning',
42 'wpstg_remote_sync_pull',
43 'wpstg_staging_create',
44 'wpstg_staging_update',
45 'wpstg_staging_reset',
46 'wpstg_staging_push',
47 ];
48
49 $wpStagingRequest = WPSTG_REQUEST;
50 if (!in_array($wpStagingRequest, $wpStagingRequests, true)) {
51 return;
52 }
53
54 $error = error_get_last();
55 if (!is_array($error)) {
56 return;
57 }
58
59 if ($error['type'] !== E_ERROR) {
60 return;
61 }
62
63 preg_match('/Allowed memory size of (\d+) bytes exhausted \(tried to allocate (\d+) bytes\)/', $error['message'], $data);
64 if (!is_array($data) || count($data) !== 3) {
65 $data['time'] = date('Y/m/d H:i:s', time());
66 $this->logSseEvent($data, false);
67 $this->releaseProcessLock();
68 return;
69 }
70
71
72 $errorTmpFile = WPSTG_UPLOADS_DIR . $wpStagingRequest . self::ERROR_FILE_EXTENSION;
73
74 $fileHandler = fopen($errorTmpFile, 'w');
75
76 $data = [
77 'memoryUsage' => memory_get_usage(true),
78 'peakMemoryUsage' => memory_get_peak_usage(true),
79 'phpMemoryLimit' => ini_get('memory_limit'),
80 'wpMemoryLimit' => defined('WP_MEMORY_LIMIT') ? WP_MEMORY_LIMIT : '',
81 'allowedMemoryLimit' => $data[1],
82 'exhaustedMemorySize' => $data[2],
83 'time' => date('Y/m/d H:i:s', time()),
84 ];
85
86 if (is_resource($fileHandler)) {
87 fwrite($fileHandler, json_encode($data));
88 fclose($fileHandler);
89 }
90
91 $this->logSseEvent($data);
92 $this->releaseProcessLock();
93 }
94
95
96
97
98
99
100
101
102 private function releaseProcessLock()
103 {
104 try {
105 WPStaging::make(ProcessLock::class)->unlockProcess();
106 } catch (\Throwable $e) {
107
108 }
109 }
110
111 private function logSseEvent(array $data, bool $isMemoryExhaust = true)
112 {
113
114
115
116 $jobTransientCache = WPStaging::make(JobTransientCache::class);
117
118 $jobId = $jobTransientCache->getJobId();
119 if (empty($jobId)) {
120 return;
121 }
122
123 if ($isMemoryExhaust) {
124 $exhaustedMemorySize = isset($data['exhaustedMemorySize']) ? (int)$data['exhaustedMemorySize'] : 0;
125 $memoryUsage = isset($data['memoryUsage']) ? (int)$data['memoryUsage'] : 0;
126 $peakMemoryUsage = isset($data['peakMemoryUsage']) ? (int)$data['peakMemoryUsage'] : 0;
127 $allowedMemoryLimit = isset($data['allowedMemoryLimit']) ? (int)$data['allowedMemoryLimit'] : 0;
128 $phpMemoryLimit = isset($data['phpMemoryLimit']) ? $data['phpMemoryLimit'] : ini_get('memory_limit');
129 $wpMemoryLimit = isset($data['wpMemoryLimit']) ? $data['wpMemoryLimit'] : (defined('WP_MEMORY_LIMIT') ? WP_MEMORY_LIMIT : '');
130
131 $message = sprintf(
132 esc_html__('Memory exhaust issue is detected during the process. Error occurred when allocating more %s on top of current usage of %s. Peak memory usage: %s, Allowed memory limit: %s, PHP memory limit: %s, WP memory limit: %s', 'wp-staging'),
133 size_format($exhaustedMemorySize),
134 size_format($memoryUsage),
135 size_format($peakMemoryUsage),
136 size_format($allowedMemoryLimit),
137 $phpMemoryLimit,
138 $wpMemoryLimit
139 );
140 } else {
141 $message = sprintf(
142 esc_html__('Job failed due to a fatal error! Error data: %s', 'wp-staging'),
143 esc_html(print_r($data, true))
144 );
145 }
146
147 $data['jobId'] = $jobId;
148 $data['message'] = $message;
149
150
151
152
153 $sseEventCache = WPStaging::make(SseEventCache::class);
154 $sseEventCache->setJobId($jobId);
155 $sseEventCache->load();
156 $sseEventCache->push([
157 'type' => $isMemoryExhaust ? SseEventCache::EVENT_TYPE_MEMORY_EXHAUST : SseEventCache::EVENT_TYPE_FATAL_ERROR,
158 'data' => $data,
159 ]);
160
161 $jobTransientCache->failJob('', $message);
162 }
163 }
164