Skip to content

Add configurable debug mode #93

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Apr 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,36 @@ mapping_aware_service:
tags: ['json_rpc_http_server.method_aware']
```

## Debug mode

You can setup 'debug' mode for the JSON-RPC server, which allows display of verbose error information within the response JSON body.
This information contains actual exception class name, code, message and stack trace.

> Note: you should never enable 'debug' mode in 'production' environment, since it will expose vital internal information to the API consumer.

Configuration example:

```yaml
# file 'config/packages/json_rpc.yaml'
json_rpc_http_server:
endpoint: '/json-rpc'
debug:
enabled: false
max_trace_size: 10
show_trace_arguments: true
simplify_trace_arguments: true

when@dev:
json_rpc_http_server:
debug:
enabled: true

when@test:
json_rpc_http_server:
debug:
enabled: true
```

## Contributing

See [contributing note](./CONTRIBUTING.md)
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"symfony/event-dispatcher-contracts": "^1.0 || ^2.0 || ^3.0",
"symfony/http-foundation": "^4.4 || ^5.4 || ^6.0",
"symfony/http-kernel": "^4.4 || ^5.4 || ^6.0",
"yoanm/jsonrpc-server-sdk": "^3.0"
"yoanm/jsonrpc-server-sdk": "^3.3"
},
"require-dev": {
"behat/behat": "^3.9.0",
Expand Down
24 changes: 24 additions & 0 deletions src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,30 @@ public function getConfigTreeBuilder()
->treatNullLike(self::DEFAULT_ENDPOINT)
->defaultValue(self::DEFAULT_ENDPOINT)
->end()
->arrayNode('debug')
->addDefaultsIfNotSet()
->children()
->booleanNode('enabled')
->info(
'Whether to render debug information on error or not (should NOT be enabled on prod)'
)
->defaultFalse()
->end()
->integerNode('max_trace_size')
->info('Max debug trace size')
->min(0)
->defaultValue(10)
->end()
->booleanNode('show_trace_arguments')
->info('Whether to render debug stack trace arguments or not')
->defaultValue(true)
->end()
->booleanNode('simplify_trace_arguments')
->info('Whether to simplify representation of debug stack trace arguments or not')
->defaultValue(true)
->end()
->end()
->end()
->end()
;

Expand Down
25 changes: 18 additions & 7 deletions src/DependencyInjection/JsonRpcHttpServerExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
use Yoanm\JsonRpcServer\Domain\JsonRpcMethodAwareInterface;

/**
* Class JsonRpcHttpServerExtension
* @see \Yoanm\SymfonyJsonRpcHttpServer\DependencyInjection\Configuration
*/
class JsonRpcHttpServerExtension implements ExtensionInterface, CompilerPassInterface
{
Expand Down Expand Up @@ -66,7 +66,8 @@ public function process(ContainerBuilder $container)
{
$this->bindJsonRpcServerDispatcher($container);
$this->bindValidatorIfDefined($container);
$this->binJsonRpcMethods($container);
$this->bindJsonRpcMethods($container);
$this->bindDebug($container);
}

/**
Expand Down Expand Up @@ -102,17 +103,19 @@ private function compileAndProcessConfigurations(array $configs, ContainerBuilde
$configuration = new Configuration();
$config = (new Processor())->processConfiguration($configuration, $configs);

$httpEndpointPath = $config['endpoint'];
$container->setParameter(self::ENDPOINT_PATH_CONTAINER_PARAM_ID, $config['endpoint']);

$container->setParameter(self::ENDPOINT_PATH_CONTAINER_PARAM_ID, $httpEndpointPath);
foreach ($config['debug'] as $name => $value) {
$container->setParameter(self::EXTENSION_IDENTIFIER.'.debug.'.$name, $value);
}
}

/**
* @param ContainerBuilder $container
*/
private function bindJsonRpcServerDispatcher(ContainerBuilder $container) : void
{
$dispatcherRef = new Reference('json_rpc_http_server.dispatcher.server');
$dispatcherRef = new Reference(self::EXTENSION_IDENTIFIER.'.dispatcher.server');
$dispatcherAwareServiceList = $container->findTaggedServiceIds(self::JSONRPC_SERVER_DISPATCHER_AWARE_TAG);
foreach ($dispatcherAwareServiceList as $serviceId => $tagAttributeList) {
$definition = $container->getDefinition($serviceId);
Expand Down Expand Up @@ -149,7 +152,7 @@ private function bindValidatorIfDefined(ContainerBuilder $container) : void
/**
* @param ContainerBuilder $container
*/
private function binJsonRpcMethods(ContainerBuilder $container) : void
private function bindJsonRpcMethods(ContainerBuilder $container) : void
{
$mappingAwareServiceDefinitionList = $this->findAndValidateMappingAwareDefinitionList($container);

Expand All @@ -166,7 +169,7 @@ private function binJsonRpcMethods(ContainerBuilder $container) : void

// Service locator for method resolver
// => first argument is an array of wanted service with keys as alias for internal use
$container->getDefinition('json_rpc_http_server.service_locator.method_resolver')
$container->getDefinition(self::EXTENSION_IDENTIFIER.'.service_locator.method_resolver')
->setArgument(0, $methodMappingList);
}

Expand Down Expand Up @@ -223,4 +226,12 @@ private function checkMethodAwareServiceIdList(
));
}
}

private function bindDebug(ContainerBuilder $container) : void
{
if ($container->getParameter(self::EXTENSION_IDENTIFIER.'.debug.enabled')) {
$container->getDefinition('json_rpc_server_sdk.app.serialization.jsonrpc_response_normalizer')
->addArgument(new Reference('json_rpc_server_sdk.app.serialization.jsonrpc_response_error_normalizer'));
}
}
}
2 changes: 1 addition & 1 deletion src/JsonRpcHttpServerBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
use Symfony\Component\HttpKernel\Bundle\Bundle;

/**
* Class JsonRpcHttpServerBundle
* @see \Yoanm\SymfonyJsonRpcHttpServer\DependencyInjection\JsonRpcHttpServerExtension
*/
class JsonRpcHttpServerBundle extends Bundle
{
Expand Down
12 changes: 10 additions & 2 deletions src/Resources/config/sdk.services.app.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
services:
#Serialization
# Serialization
json_rpc_server_sdk.app.serialization.jsonrpc_request_denormalizer:
class: Yoanm\JsonRpcServer\App\Serialization\JsonRpcRequestDenormalizer

Expand All @@ -22,7 +22,7 @@ services:
- '@json_rpc_server_sdk.app.serialization.jsonrpc_call_dernormalizer'
- '@json_rpc_server_sdk.app.serialization.jsonrpc_call_response_normalizer'

#Handlers
# Handlers
json_rpc_server_sdk.app.handler.jsonrpc_request:
class: Yoanm\JsonRpcServer\App\Handler\JsonRpcRequestHandler
arguments:
Expand All @@ -39,3 +39,11 @@ services:
# Creator
json_rpc_server_sdk.app.creator.response:
class: Yoanm\JsonRpcServer\App\Creator\ResponseCreator

# Debug
json_rpc_server_sdk.app.serialization.jsonrpc_response_error_normalizer:
class: Yoanm\JsonRpcServer\App\Serialization\JsonRpcResponseErrorNormalizer
arguments:
- '%json_rpc_http_server.debug.max_trace_size%'
- '%json_rpc_http_server.debug.show_trace_arguments%'
- '%json_rpc_http_server.debug.simplify_trace_arguments%'
6 changes: 6 additions & 0 deletions tests/Functional/DependencyInjection/ConfigFilesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Yoanm\JsonRpcServer\App\Serialization\JsonRpcCallSerializer;
use Yoanm\JsonRpcServer\App\Serialization\JsonRpcRequestDenormalizer;
use Yoanm\JsonRpcServer\App\Serialization\JsonRpcResponseNormalizer;
use Yoanm\JsonRpcServer\App\Serialization\JsonRpcResponseErrorNormalizer;
use Yoanm\JsonRpcServer\Infra\Endpoint\JsonRpcEndpoint;
use Yoanm\SymfonyJsonRpcHttpServer\DependencyInjection\JsonRpcHttpServerExtension;
use Yoanm\SymfonyJsonRpcHttpServer\Dispatcher\SymfonyJsonRpcServerDispatcher;
Expand Down Expand Up @@ -100,6 +101,11 @@ public function provideSDKAppServiceIdAndClass()
'serviceClassName' => ResponseCreator::class,
'public' => false,
],
'SDK - App - Response error normalizer' => [
'serviceId' => 'json_rpc_server_sdk.app.serialization.jsonrpc_response_error_normalizer',
'serviceClassName' => JsonRpcResponseErrorNormalizer::class,
'public' => false,
],
];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,4 +185,22 @@ public function testShouldThowAnExceptionIfMethodAwareServiceDoesNotImplementRig

$this->loadContainer();
}

public function testShouldAddDebugResponseErrorNormalizerIfDebugModeEnabled()
{
$this->loadContainer([
'debug' => [
'enabled' => true,
]
]);

// Assert response normalizer has responseErrorNormalizer as first argument
$this->assertContainerBuilderHasServiceDefinitionWithArgument(
'json_rpc_server_sdk.app.serialization.jsonrpc_response_normalizer',
0,
new Reference('json_rpc_server_sdk.app.serialization.jsonrpc_response_error_normalizer'),
);

$this->assertEndpointIsUsable();
}
}