w7corp/easywechat · warning · BadMethodCallException
%s does't implements %s
Error message
%s does't implements %s
What it means
Response::toStream() can only stream when the wrapped Symfony response implements StreamableInterface; the fallback path (used for MockResponse and other non-streamable responses) returns a mock stream when $throw is falsy, but throws BadMethodCallException("<class> does't implements ...") when $throw is true. The library is telling you the concrete response class cannot provide a PHP stream resource.
Source
Thrown at src/Kernel/HttpClient/Response.php:133
public function toJson(?bool $throw = null): string|false
{
return json_encode($this->toArray($throw), JSON_UNESCAPED_UNICODE);
}
/**
* {@inheritdoc}
*
* @throws BadMethodCallException
*/
public function toStream(?bool $throw = null)
{
if ($this->response instanceof StreamableInterface) {
return $this->response->toStream($throw ?? $this->throw);
}
if ($throw) {
throw new BadMethodCallException(sprintf('%s does\'t implements %s', \get_class($this->response), StreamableInterface::class));
}
return StreamWrapper::createResource(new MockResponse);
}
/**
* @throws \LogicException
*/
public function toDataUrl(): string
{
return 'data:'.$this->getHeaderLine('content-type').';base64,'.base64_encode($this->getContent());
}
public function toPsrResponse(?ResponseFactoryInterface $responseFactory = null, ?StreamFactoryInterface $streamFactory = null): \Psr\Http\Message\ResponseInterface
{
$streamFactory ??= $responseFactory instanceof StreamFactoryInterface ? $responseFactory : null;
if ($responseFactory === null || $streamFactory === null) {View on GitHub (pinned to f0cf0a8b83)
Solutions
- Do not pass true: call $response->toStream() and let it fall back when streaming is unsupported
- In tests, provide a response that implements StreamableInterface if you need a real stream
- For large downloads prefer saveAs($path) or toDataUrl() over streaming
Example fix
// before $stream = $response->toStream(true); // throws for MockResponse // after $stream = $response->toStream(); // mock fallback, no exception
Defensive patterns
Strategy: try-catch
Try / catch
try {
$stream = $response->toStream(true);
} catch (\BadMethodCallException $e) {
// underlying response (e.g. MockResponse in tests) cannot stream
$stream = $response->toStream(); // mock fallback
} Prevention
- Do not force throw=true on toStream(); let the library fall back
- In tests, exercise streaming with a real HTTP response or skip stream assertions for mocked clients
- Prefer saveAs() for large payloads
When it happens
Trigger: Calling toStream(true) on a Response wrapping a Symfony HttpClient MockResponse (unit tests) or any response class lacking StreamableInterface.
Common situations: Test suites mocking HttpClient responses, custom response wrappers injected into the client, code paths that force throw=true unconditionally.
Related errors
- The type of `xml` must be string or array.
- The type of `json` must be string or array.
- The method "%s" is not supported.
- Response body is empty.
- 400
AI-assisted analysis of w7corp/easywechat@f0cf0a8b83 (2026-08-21).
Data as JSON: /api/errors/4a67ba523545b5f1.
Report an issue: GitHub.