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