Skip to content

Commit 64c00d3

Browse files
Deal with large payloads and batching correctly
1 parent c0468b6 commit 64c00d3

1 file changed

Lines changed: 58 additions & 1 deletion

File tree

src/Bugsnag/Notification.php

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,25 @@ public function deliver()
137137
*/
138138
public function postJSON($url, $data)
139139
{
140-
$body = json_encode($data);
140+
// Try to send the whole lot, or without the meta data for the first
141+
// event. If failed, try to send the first event, and then the rest of
142+
// them, revursively. Decrease by a constant and concquer if you like.
143+
// Note that the base case is satisfied as soon as the payload is small
144+
// enought to send, or when it's simply discarded.
145+
try {
146+
$body = self::encode($data);
147+
} catch (RuntimeException $e) {
148+
if (count($data['events']) > 1) {
149+
$event = array_shift($data['events']);
150+
$this->postJSON($url, array_merge($data, ['events' => [$event]]));
151+
$this->postJSON($url, $data);
152+
}
141153

154+
error_log('Bugsnag Warning: '.$e->getMessage());
155+
156+
return;
157+
}
158+
142159
// Prefer cURL if it is installed, otherwise fall back to fopen()
143160
// cURL supports both timeouts and proxies
144161
if (function_exists('curl_version')) {
@@ -150,6 +167,46 @@ public function postJSON($url, $data)
150167
}
151168
}
152169

170+
/**
171+
* Json encode the given data.
172+
*
173+
* We will also strip out the meta data if it's too large.
174+
*
175+
* @param array $data the data to encode
176+
*
177+
* @throws RuntimeException
178+
*
179+
* @return string
180+
*/
181+
private function encode(array $data)
182+
{
183+
$body = json_encode($data);
184+
185+
if (self::length($body) > 500000) {
186+
unset($data['events'][0]['metaData']);
187+
}
188+
189+
$body = json_encode($data);
190+
191+
if (self::length($body) > 500000) {
192+
throw new RuntimeException('Payload too large');
193+
}
194+
195+
return $body;
196+
}
197+
198+
/**
199+
* Get the length of the given string in bytes.
200+
*
201+
* @param string $str the string to get the length of
202+
*
203+
* @return int
204+
*/
205+
private function length($str)
206+
{
207+
return function_exists('mb_strlen') ? mb_strlen($str, '8bit') : strlen($str);
208+
}
209+
153210
/**
154211
* Post the given info to Bugsnag using cURL.
155212
*

0 commit comments

Comments
 (0)