PluginProbe ʕ •ᴥ•ʔ
WP STAGING – WordPress Backups, Restore, Migration & Clone / 4.11.1
WP STAGING – WordPress Backups, Restore, Migration & Clone v4.11.1
4.11.1 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 1 week ago Analytics 1 week ago Assets 1 week ago BackgroundProcessing 1 week ago CloningProcess 6 days ago Collection 1 week ago Command 1 week ago Component 1 week ago DI 1 week ago Database 6 days ago DependencyResolver 1 week ago Exceptions 2 years ago Experiments 1 week ago Facades 1 week ago Filesystem 1 week ago Interfaces 1 week ago Job 6 days ago Language 1 week ago Logger 1 week ago Mails 1 week ago Network 1 week ago Newsfeed 1 week ago Notices 6 days ago Onboarding 6 days ago Performance 1 week ago Permalinks 1 week ago Queue 1 week ago Rest 1 week ago Security 1 week ago Settings 1 week ago TemplateEngine 1 week ago ThirdParty 1 week ago Traits 6 days ago Upgrade 1 week ago Utils 6 days ago AnalyticsServiceProvider.php 1 week ago AssetServiceProvider.php 1 year ago CommonServiceProvider.php 6 days ago ErrorHandler.php 1 week ago NoticeServiceProvider.php 1 year ago SettingsServiceProvider.php 4 months ago SiteInfo.php 6 days ago Url.php 1 week 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