w7corp/easywechat · error · BadResponseException
Response body is empty.
Error message
Response body is empty.
What it means
Response::toArray() requires a non-empty body: it calls the underlying Symfony response's getContent($throw) and throws BadResponseException('Response body is empty.') when the content is ''. The HTTP exchange completed but returned zero bytes — empty 2xx, an error status with an empty body (when throw=false), or a proxied response with no payload.
Source
Thrown at src/Kernel/HttpClient/Response.php:98
return (bool) ($this->failureJudge)($this);
}
try {
return $this->getStatusCode() >= 400;
} catch (Throwable $e) {
return true;
}
}
/**
* @throws BadResponseException
*/
public function toArray(?bool $throw = null): array
{
$throw ??= $this->throw;
if ('' === $content = $this->response->getContent($throw)) {
throw new BadResponseException('Response body is empty.');
}
$contentType = $this->getHeaderLine('content-type', $throw);
if (str_contains($contentType, 'text/xml')
|| str_contains($contentType, 'application/xml')
|| str_starts_with($content, '<xml>')) {
try {
return Xml::parse($content) ?? [];
} catch (Throwable $e) {
throw new BadResponseException('Response body is not valid xml.', 400, $e);
}
}
return $this->response->toArray($throw);
}
public function toJson(?bool $throw = null): string|falseView on GitHub (pinned to f0cf0a8b83)
Solutions
- Check the status code first: $response->getStatusCode() and $response->getContent(false) before parsing
- Use saveAs($path) for binary/media downloads instead of toArray()
- Log the raw exchange (url, status, headers) when it fires to identify the empty-body source
Example fix
// before
$data = $response->toArray(); // throws when body is empty
// after
if ($response->getStatusCode() !== 200 || '' === $response->getContent(false)) {
throw new RuntimeException('Unexpected empty response: HTTP '.$response->getStatusCode());
}
$data = $response->toArray(); Defensive patterns
Strategy: validation
Validate before calling
// Guard before parsing
$content = $response->getContent(false);
if ('' === $content) {
$status = $response->getStatusCode();
throw new RuntimeException("WeChat returned an empty body (HTTP {$status})");
}
$data = $response->toArray(); Try / catch
try {
$data = $response->toArray();
} catch (\Symfony\Component\HttpClient\Exception\BadResponseException $e) {
if (str_contains($e->getMessage(), 'empty')) {
// empty body: decide per endpoint (retry / treat as error / ignore)
$data = [];
} else {
throw $e;
}
} Prevention
- Always check status code and content before parsing WeChat responses
- Use saveAs() for binary downloads; never toArray() on media endpoints
- Alert on empty-body rates — they usually indicate gateway trouble
When it happens
Trigger: Calling toArray() on a media/binary download response, on a response whose status is 3xx/4xx/5xx with empty body (e.g. after getStatusCode() was not checked), or on a callback verification GET request that WeChat answers with an empty echo body.
Common situations: Using toArray() where saveAs() is needed (downloads), gateways/proxies stripping error bodies, WeChat returning empty body on some rate-limit/refused paths, following redirects to empty endpoints.
Related errors
- 400
- The type of `xml` must be string or array.
- The type of `json` must be string or array.
- The method "%s" is not supported.
- %s does't implements %s
AI-assisted analysis of w7corp/easywechat@f0cf0a8b83 (2026-08-21).
Data as JSON: /api/errors/9eb0af63f2df78bf.
Report an issue: GitHub.