Я использую Serverless Framework для развертывания своего PHP-кода в качестве IBM Cloud Function.
Вот код из файла действия PHP:
function main($args): array {
Sentry\init(['dsn' => 'SENTRY_DSN' ]);
try {
throw new \Exception('Some error')
} catch (\Throwable $exception) {
Sentry\captureException($exception);
}
}
А это файл serverless.yml:
service: cloudfunc
provider:
name: openwhisk
runtime: php
package:
individually: true
exclude:
- "**"
include:
- "vendor/**"
functions:
test-sentry:
handler: actions/test-sentry.main
annotations:
raw-http: true
events:
- http:
path: /test-sentry
method: post
resp: http
package:
include:
- actions/test-sentry.php
plugins:
- serverless-openwhisk
Когда я тестирую обработчик действий из своей локальной среды (контейнеры NGINX / PHP Docker), ошибки отправляются в Sentry.
Но когда я пытаюсь вызвать действие из IBM Cloud, в консоли Sentry ничего не появляется.
Edit:
Через некоторое время, пытаясь выяснить источник проблемы, я обнаружил, что она связана с асинхронной природой отправки http-запроса в Sentry (у меня есть другие библиотеки, которые устанавливают HTTP / TCP-соединения с Loggly, RabbitMQ, MySQL, и все они работа как положено):
vendor/sentry/sentry/src/Transport/HttpTransport.php
в методе send, куда отправляется фактический http-запрос:
public function send(Event $event): ?string
{
$request = $this->requestFactory->createRequest(
'POST',
sprintf('/api/%d/store/', $this->config->getProjectId()),
['Content-Type' => 'application/json'],
JSON::encode($event)
);
$promise = $this->httpClient->sendAsyncRequest($request);
//The promise state here is "pending"
//This line here is being logged in the stdout of the invoked action
var_dump($promise->getState());
// This function is defined in-line so it doesn't show up for type-hinting
$cleanupPromiseCallback = function ($responseOrException) use ($promise) {
//The promise state here is "fulfilled"
//This line here is never logged in the stdout of the invoked action
//Like the execution never happens here
var_dump($promise->getState());
$index = array_search($promise, $this->pendingRequests, true);
if (false !== $index) {
unset($this->pendingRequests[$index]);
}
return $responseOrException;
};
$promise->then($cleanupPromiseCallback, $cleanupPromiseCallback);
$this->pendingRequests[] = $promise;
return $event->getId();
}