Enable Discovery debug logging for production troubleshooting
- Add DISCOVERY_LOG_LEVEL=debug - Add DISCOVERY_SHOW_PROGRESS=true - Temporary changes for debugging InitializerProcessor fixes on production
This commit is contained in:
155
src/Framework/Webhook/Middleware/WebhookMiddleware.php
Normal file
155
src/Framework/Webhook/Middleware/WebhookMiddleware.php
Normal file
@@ -0,0 +1,155 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Framework\Webhook\Middleware;
|
||||
|
||||
use App\Framework\Core\Environment;
|
||||
use App\Framework\Http\HttpMiddleware;
|
||||
use App\Framework\Http\JsonResponse;
|
||||
use App\Framework\Http\MiddlewareContext;
|
||||
use App\Framework\Http\Next;
|
||||
use App\Framework\Http\RequestStateManager;
|
||||
use App\Framework\Http\Response;
|
||||
use App\Framework\Logging\Logger;
|
||||
use App\Framework\Webhook\Attributes\WebhookEndpoint;
|
||||
use App\Framework\Webhook\Processing\WebhookRequestHandler;
|
||||
use App\Framework\Webhook\ValueObjects\WebhookProvider;
|
||||
use ReflectionMethod;
|
||||
|
||||
/**
|
||||
* Automatic webhook processing middleware
|
||||
* Intercepts routes marked with WebhookEndpoint attribute for automatic handling
|
||||
*/
|
||||
final readonly class WebhookMiddleware implements HttpMiddleware
|
||||
{
|
||||
public function __construct(
|
||||
private WebhookRequestHandler $webhookHandler,
|
||||
private Environment $environment,
|
||||
private Logger $logger
|
||||
) {
|
||||
}
|
||||
|
||||
public function __invoke(MiddlewareContext $context, Next $next, RequestStateManager $stateManager): MiddlewareContext
|
||||
{
|
||||
$request = $context->request;
|
||||
|
||||
// Check if route has WebhookEndpoint attribute
|
||||
$webhookAttribute = $this->extractWebhookAttribute($stateManager);
|
||||
|
||||
if ($webhookAttribute === null) {
|
||||
// No webhook attribute - continue normally
|
||||
return $next($context);
|
||||
}
|
||||
|
||||
// Get webhook configuration from environment
|
||||
$webhookConfig = $this->getWebhookConfig($webhookAttribute->provider);
|
||||
|
||||
if ($webhookConfig === null) {
|
||||
$this->logger->warning('Webhook configuration not found', [
|
||||
'provider' => $webhookAttribute->provider,
|
||||
'endpoint' => $request->getPath(),
|
||||
]);
|
||||
|
||||
// Return error response
|
||||
$errorResponse = new JsonResponse([
|
||||
'status' => 'error',
|
||||
'message' => 'Webhook configuration not found',
|
||||
'provider' => $webhookAttribute->provider,
|
||||
], 500);
|
||||
|
||||
return $context->withResponse($errorResponse);
|
||||
}
|
||||
|
||||
// Process webhook using WebhookRequestHandler
|
||||
try {
|
||||
$provider = WebhookProvider::fromString($webhookAttribute->provider);
|
||||
|
||||
$webhookResponse = $this->webhookHandler->handle(
|
||||
request: $request,
|
||||
provider: $provider,
|
||||
secret: $webhookConfig['secret'],
|
||||
allowedEvents: $webhookAttribute->events
|
||||
);
|
||||
|
||||
// Store webhook processing result in request state
|
||||
$stateManager->set('webhook.processed', true);
|
||||
$stateManager->set('webhook.provider', $webhookAttribute->provider);
|
||||
$stateManager->set('webhook.async', $webhookAttribute->async);
|
||||
|
||||
// Return webhook processing response
|
||||
return $context->withResponse($webhookResponse);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error('Webhook middleware processing failed', [
|
||||
'provider' => $webhookAttribute->provider,
|
||||
'endpoint' => $request->getPath(),
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
|
||||
// Store error in request state
|
||||
$stateManager->set('webhook.error', $e->getMessage());
|
||||
|
||||
// Return error response
|
||||
$errorResponse = new JsonResponse([
|
||||
'status' => 'error',
|
||||
'message' => 'Webhook processing failed',
|
||||
'provider' => $webhookAttribute->provider,
|
||||
'error' => $e->getMessage(),
|
||||
], 500);
|
||||
|
||||
return $context->withResponse($errorResponse);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract WebhookEndpoint attribute from request state or route info
|
||||
*/
|
||||
private function extractWebhookAttribute(RequestStateManager $stateManager): ?WebhookEndpoint
|
||||
{
|
||||
// Try to get route info from request state
|
||||
$routeInfo = $stateManager->get('_route_info');
|
||||
|
||||
if (! $routeInfo || ! isset($routeInfo['controller'], $routeInfo['method'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
$reflection = new ReflectionMethod($routeInfo['controller'], $routeInfo['method']);
|
||||
$attributes = $reflection->getAttributes(WebhookEndpoint::class);
|
||||
|
||||
if (empty($attributes)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $attributes[0]->newInstance();
|
||||
|
||||
} catch (\ReflectionException $e) {
|
||||
$this->logger->debug('Could not extract webhook attribute', [
|
||||
'controller' => $routeInfo['controller'],
|
||||
'method' => $routeInfo['method'],
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get webhook configuration from environment for provider
|
||||
*/
|
||||
private function getWebhookConfig(string $provider): ?array
|
||||
{
|
||||
$envKey = strtoupper("WEBHOOK_{$provider}_SECRET");
|
||||
$secret = $this->environment->get($envKey);
|
||||
|
||||
if (empty($secret)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return [
|
||||
'secret' => $secret,
|
||||
'provider' => $provider,
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user