danielfm / pybreaker

Python implementation of the Circuit Breaker pattern.
BSD 3-Clause "New" or "Revised" License
508 stars 74 forks source link

Adding settings to allow passing THROW_NEW_ERROR_ON_TRIP #61

Closed Cruuncher closed 2 years ago

Cruuncher commented 2 years ago

Fix for https://github.com/danielfm/pybreaker/issues/60

The setting lets you alter the default behaviour of throwing a new CircuitBreakerError every time the circuit opens. By setting THROW_NEW_ERROR_ON_TRIP to False, the original exception will be preserved when the circuit breaker opens

The default value for this setting is True, which mimics the current behaviour of the library.

Cruuncher commented 2 years ago

running test
WARNING: Testing via this command is deprecated and will be removed in a future version. Users looking for a generic test entry point independent of test runner are encouraged to use tox.
running egg_info
writing src/pybreaker.egg-info/PKG-INFO
writing dependency_links to src/pybreaker.egg-info/dependency_links.txt
writing requirements to src/pybreaker.egg-info/requires.txt
writing top-level names to src/pybreaker.egg-info/top_level.txt
reading manifest file 'src/pybreaker.egg-info/SOURCES.txt'
adding license file 'LICENSE'
writing manifest file 'src/pybreaker.egg-info/SOURCES.txt'
running build_ext
test_fail_max_thread_safety (tests.CircuitBreakerRedisConcurrencyTestCase)
CircuitBreaker: it should not allow more failed calls than 'fail_max' ... ok
test_fail_thread_safety (tests.CircuitBreakerRedisConcurrencyTestCase)
CircuitBreaker: it should compute a failed call atomically to ... ok
test_half_open_thread_safety (tests.CircuitBreakerRedisConcurrencyTestCase)
CircuitBreaker: it should allow only one trial call when the ... ok
test_success_thread_safety (tests.CircuitBreakerRedisConcurrencyTestCase)
CircuitBreaker: it should compute a successful call atomically ... ok
test_call_events (tests.CircuitBreakerRedisTestCase)
CircuitBreaker: it should call the appropriate functions on every ... ok
test_close (tests.CircuitBreakerRedisTestCase)
CircuitBreaker: it should allow the circuit to be closed manually. ... ok
test_contextmanager (tests.CircuitBreakerRedisTestCase)
CircuitBreaker: it should catch in a with statement ... ok
test_failed_call_after_timeout (tests.CircuitBreakerRedisTestCase)
CircuitBreaker: it should half-open the circuit after timeout. ... ok
test_failed_call_when_halfopen (tests.CircuitBreakerRedisTestCase)
CircuitBreaker: it should open the circuit when a call fails in ... ok
test_fallback_state (tests.CircuitBreakerRedisTestCase) ... ok
test_generator (tests.CircuitBreakerRedisTestCase)
CircuitBreaker: it should inspect generator values. ... ok
test_missing_state (tests.CircuitBreakerRedisTestCase)
CircuitBreakerRedis: If state on Redis is missing, it should set the ... ok
test_namespace (tests.CircuitBreakerRedisTestCase) ... ok
test_one_failed_call (tests.CircuitBreakerRedisTestCase)
CircuitBreaker: it should keep the circuit closed after a few ... ok
test_one_successful_call_after_failed_call (tests.CircuitBreakerRedisTestCase)
CircuitBreaker: it should keep the circuit closed after few mixed ... ok
test_several_failed_calls_setting_absent (tests.CircuitBreakerRedisTestCase)
CircuitBreaker: it should open the circuit after many failures. ... ok
test_successful_after_timeout (tests.CircuitBreakerRedisTestCase)
CircuitBreaker: it should close the circuit when a call succeeds ... ok
test_successful_call (tests.CircuitBreakerRedisTestCase)
CircuitBreaker: it should keep the circuit closed after a successful ... ok
test_successful_call_when_halfopen (tests.CircuitBreakerRedisTestCase)
CircuitBreaker: it should close the circuit when a call succeeds in ... ok
test_throw_new_error_on_trip_setting_false (tests.CircuitBreakerRedisTestCase)
CircuitBreaker: it should throw the original exception ... ok
test_throw_new_error_on_trip_setting_true (tests.CircuitBreakerRedisTestCase)
CircuitBreaker: it should throw a CircuitBreakerError exception ... ok
test_traceback_in_circuitbreaker_error (tests.CircuitBreakerRedisTestCase)
CircuitBreaker: it should open the circuit after many failures. ... ok
test_transition_events (tests.CircuitBreakerRedisTestCase)
CircuitBreaker: it should call the appropriate functions on every ... ok
test_add_excluded_exception (tests.CircuitBreakerTestCase)
CircuitBreaker: it should allow the user to exclude an exception at a ... ok
test_add_excluded_exceptions (tests.CircuitBreakerTestCase)
CircuitBreaker: it should allow the user to exclude exceptions at a ... ok
test_add_listener (tests.CircuitBreakerTestCase)
CircuitBreaker: it should allow the user to add a listener at a ... ok
test_add_listeners (tests.CircuitBreakerTestCase)
CircuitBreaker: it should allow the user to add listeners at a ... ok
test_call_async_with_args (tests.CircuitBreakerTestCase)
CircuitBreaker: it should be able to invoke async functions with args. ... ok
test_call_async_with_kwargs (tests.CircuitBreakerTestCase)
CircuitBreaker: it should be able to invoke async functions with kwargs. ... ok
test_call_async_with_no_args (tests.CircuitBreakerTestCase)
CircuitBreaker: it should be able to invoke async functions with no-args. ... ok
test_call_events (tests.CircuitBreakerTestCase)
CircuitBreaker: it should call the appropriate functions on every ... ok
test_call_with_args (tests.CircuitBreakerTestCase)
CircuitBreaker: it should be able to invoke functions with args. ... ok
test_call_with_kwargs (tests.CircuitBreakerTestCase)
CircuitBreaker: it should be able to invoke functions with kwargs. ... ok
test_call_with_no_args (tests.CircuitBreakerTestCase)
CircuitBreaker: it should be able to invoke functions with no-args. ... ok
test_close (tests.CircuitBreakerTestCase)
CircuitBreaker: it should allow the circuit to be closed manually. ... ok
test_contextmanager (tests.CircuitBreakerTestCase)
CircuitBreaker: it should catch in a with statement ... ok
test_create_new_state__bad_state (tests.CircuitBreakerTestCase) ... ok
test_decorator (tests.CircuitBreakerTestCase)
CircuitBreaker: it should be a decorator. ... ok
test_decorator_call_future (tests.CircuitBreakerTestCase)
CircuitBreaker: it should be a decorator. ... ok
test_default_params (tests.CircuitBreakerTestCase)
CircuitBreaker: it should define smart defaults. ... ok
test_default_state (tests.CircuitBreakerTestCase)
CircuitBreaker: it should get initial state from state_storage. ... ok
test_excluded_callable_and_types_exceptions (tests.CircuitBreakerTestCase)
CircuitBreaker: it should allow a mix of exclusions that includes both filter functions and types. ... ok
test_excluded_callable_exceptions (tests.CircuitBreakerTestCase)
CircuitBreaker: it should ignore specific exceptions that return true from a filtering callable. ... ok
test_excluded_exceptions (tests.CircuitBreakerTestCase)
CircuitBreaker: it should ignore specific exceptions. ... ok
test_fail_max_setter (tests.CircuitBreakerTestCase)
CircuitBreaker: it should allow the user to set a new value for ... ok
test_failed_call_after_timeout (tests.CircuitBreakerTestCase)
CircuitBreaker: it should half-open the circuit after timeout. ... ok
test_failed_call_when_halfopen (tests.CircuitBreakerTestCase)
CircuitBreaker: it should open the circuit when a call fails in ... ok
test_failure_count_not_reset_during_creation (tests.CircuitBreakerTestCase) ... ok
test_generator (tests.CircuitBreakerTestCase)
CircuitBreaker: it should inspect generator values. ... ok
test_name (tests.CircuitBreakerTestCase)
CircuitBreaker: it should allow an optional name to be set and ... ok
test_new_with_custom_excluded_exceptions (tests.CircuitBreakerTestCase)
CircuitBreaker: it should support a custom list of excluded ... ok
test_new_with_custom_fail_max (tests.CircuitBreakerTestCase)
CircuitBreaker: it should support a custom maximum number of ... ok
test_new_with_custom_reset_timeout (tests.CircuitBreakerTestCase)
CircuitBreaker: it should support a custom reset timeout value. ... ok
test_no_tornado_raises (tests.CircuitBreakerTestCase) ... ok
test_notify_called_on_state_change (tests.CircuitBreakerTestCase) ... ok
test_notify_not_called_on_init (tests.CircuitBreakerTestCase) ... ok
test_one_failed_call (tests.CircuitBreakerTestCase)
CircuitBreaker: it should keep the circuit closed after a few ... ok
test_one_successful_call_after_failed_call (tests.CircuitBreakerTestCase)
CircuitBreaker: it should keep the circuit closed after few mixed ... ok
test_remove_excluded_exception (tests.CircuitBreakerTestCase)
CircuitBreaker: it should allow the user to remove an excluded ... ok
test_remove_listener (tests.CircuitBreakerTestCase)
CircuitBreaker: it should allow the user to remove a listener. ... ok
test_reset_timeout_setter (tests.CircuitBreakerTestCase)
CircuitBreaker: it should allow the user to set a new value for ... ok
test_several_failed_calls_setting_absent (tests.CircuitBreakerTestCase)
CircuitBreaker: it should open the circuit after many failures. ... ok
test_state_opened_at_not_reset_during_creation (tests.CircuitBreakerTestCase) ... ok
test_successful_after_timeout (tests.CircuitBreakerTestCase)
CircuitBreaker: it should close the circuit when a call succeeds ... ok
test_successful_call (tests.CircuitBreakerTestCase)
CircuitBreaker: it should keep the circuit closed after a successful ... ok
test_successful_call_when_halfopen (tests.CircuitBreakerTestCase)
CircuitBreaker: it should close the circuit when a call succeeds in ... ok
test_throw_new_error_on_trip_setting_false (tests.CircuitBreakerTestCase)
CircuitBreaker: it should throw the original exception ... ok
test_throw_new_error_on_trip_setting_true (tests.CircuitBreakerTestCase)
CircuitBreaker: it should throw a CircuitBreakerError exception ... ok
test_traceback_in_circuitbreaker_error (tests.CircuitBreakerTestCase)
CircuitBreaker: it should open the circuit after many failures. ... ok
test_transition_events (tests.CircuitBreakerTestCase)
CircuitBreaker: it should call the appropriate functions on every ... ok
test_fail_max_thread_safety (tests.CircuitBreakerThreadsTestCase)
CircuitBreaker: it should not allow more failed calls than ... ok
test_fail_thread_safety (tests.CircuitBreakerThreadsTestCase)
CircuitBreaker: it should compute a failed call atomically to ... ok
test_half_open_thread_safety (tests.CircuitBreakerThreadsTestCase)
CircuitBreaker: it should allow only one trial call when the ... ok
test_success_thread_safety (tests.CircuitBreakerThreadsTestCase)
CircuitBreaker: it should compute a successful call atomically ... ok

----------------------------------------------------------------------
Ran 74 tests in 6.382s

OK
(17:28:57) ~/pybreaker #: 
Cruuncher commented 2 years ago

Test run after push:


running test
WARNING: Testing via this command is deprecated and will be removed in a future version. Users looking for a generic test entry point independent of test runner are encouraged to use tox.
running egg_info
writing src/pybreaker.egg-info/PKG-INFO
writing dependency_links to src/pybreaker.egg-info/dependency_links.txt
writing requirements to src/pybreaker.egg-info/requires.txt
writing top-level names to src/pybreaker.egg-info/top_level.txt
reading manifest file 'src/pybreaker.egg-info/SOURCES.txt'
adding license file 'LICENSE'
writing manifest file 'src/pybreaker.egg-info/SOURCES.txt'
running build_ext
test_fail_max_thread_safety (tests.CircuitBreakerRedisConcurrencyTestCase)
CircuitBreaker: it should not allow more failed calls than 'fail_max' ... ok
test_fail_thread_safety (tests.CircuitBreakerRedisConcurrencyTestCase)
CircuitBreaker: it should compute a failed call atomically to ... ok
test_half_open_thread_safety (tests.CircuitBreakerRedisConcurrencyTestCase)
CircuitBreaker: it should allow only one trial call when the ... ok
test_success_thread_safety (tests.CircuitBreakerRedisConcurrencyTestCase)
CircuitBreaker: it should compute a successful call atomically ... ok
test_call_events (tests.CircuitBreakerRedisTestCase)
CircuitBreaker: it should call the appropriate functions on every ... ok
test_close (tests.CircuitBreakerRedisTestCase)
CircuitBreaker: it should allow the circuit to be closed manually. ... ok
test_contextmanager (tests.CircuitBreakerRedisTestCase)
CircuitBreaker: it should catch in a with statement ... ok
test_failed_call_after_timeout (tests.CircuitBreakerRedisTestCase)
CircuitBreaker: it should half-open the circuit after timeout. ... ok
test_failed_call_when_halfopen (tests.CircuitBreakerRedisTestCase)
CircuitBreaker: it should open the circuit when a call fails in ... ok
test_fallback_state (tests.CircuitBreakerRedisTestCase) ... ok
test_generator (tests.CircuitBreakerRedisTestCase)
CircuitBreaker: it should inspect generator values. ... ok
test_missing_state (tests.CircuitBreakerRedisTestCase)
CircuitBreakerRedis: If state on Redis is missing, it should set the ... ok
test_namespace (tests.CircuitBreakerRedisTestCase) ... ok
test_one_failed_call (tests.CircuitBreakerRedisTestCase)
CircuitBreaker: it should keep the circuit closed after a few ... ok
test_one_successful_call_after_failed_call (tests.CircuitBreakerRedisTestCase)
CircuitBreaker: it should keep the circuit closed after few mixed ... ok
test_several_failed_calls_setting_absent (tests.CircuitBreakerRedisTestCase)
CircuitBreaker: it should open the circuit after many failures. ... ok
test_successful_after_timeout (tests.CircuitBreakerRedisTestCase)
CircuitBreaker: it should close the circuit when a call succeeds ... ok
test_successful_call (tests.CircuitBreakerRedisTestCase)
CircuitBreaker: it should keep the circuit closed after a successful ... ok
test_successful_call_when_halfopen (tests.CircuitBreakerRedisTestCase)
CircuitBreaker: it should close the circuit when a call succeeds in ... ok
test_throw_new_error_on_trip_false (tests.CircuitBreakerRedisTestCase)
CircuitBreaker: it should throw the original exception ... ok
test_throw_new_error_on_trip_true (tests.CircuitBreakerRedisTestCase)
CircuitBreaker: it should throw a CircuitBreakerError exception ... ok
test_traceback_in_circuitbreaker_error (tests.CircuitBreakerRedisTestCase)
CircuitBreaker: it should open the circuit after many failures. ... ok
test_transition_events (tests.CircuitBreakerRedisTestCase)
CircuitBreaker: it should call the appropriate functions on every ... ok
test_add_excluded_exception (tests.CircuitBreakerTestCase)
CircuitBreaker: it should allow the user to exclude an exception at a ... ok
test_add_excluded_exceptions (tests.CircuitBreakerTestCase)
CircuitBreaker: it should allow the user to exclude exceptions at a ... ok
test_add_listener (tests.CircuitBreakerTestCase)
CircuitBreaker: it should allow the user to add a listener at a ... ok
test_add_listeners (tests.CircuitBreakerTestCase)
CircuitBreaker: it should allow the user to add listeners at a ... ok
test_call_async_with_args (tests.CircuitBreakerTestCase)
CircuitBreaker: it should be able to invoke async functions with args. ... ok
test_call_async_with_kwargs (tests.CircuitBreakerTestCase)
CircuitBreaker: it should be able to invoke async functions with kwargs. ... ok
test_call_async_with_no_args (tests.CircuitBreakerTestCase)
CircuitBreaker: it should be able to invoke async functions with no-args. ... ok
test_call_events (tests.CircuitBreakerTestCase)
CircuitBreaker: it should call the appropriate functions on every ... ok
test_call_with_args (tests.CircuitBreakerTestCase)
CircuitBreaker: it should be able to invoke functions with args. ... ok
test_call_with_kwargs (tests.CircuitBreakerTestCase)
CircuitBreaker: it should be able to invoke functions with kwargs. ... ok
test_call_with_no_args (tests.CircuitBreakerTestCase)
CircuitBreaker: it should be able to invoke functions with no-args. ... ok
test_close (tests.CircuitBreakerTestCase)
CircuitBreaker: it should allow the circuit to be closed manually. ... ok
test_contextmanager (tests.CircuitBreakerTestCase)
CircuitBreaker: it should catch in a with statement ... ok
test_create_new_state__bad_state (tests.CircuitBreakerTestCase) ... ok
test_decorator (tests.CircuitBreakerTestCase)
CircuitBreaker: it should be a decorator. ... ok
test_decorator_call_future (tests.CircuitBreakerTestCase)
CircuitBreaker: it should be a decorator. ... ok
test_default_params (tests.CircuitBreakerTestCase)
CircuitBreaker: it should define smart defaults. ... ok
test_default_state (tests.CircuitBreakerTestCase)
CircuitBreaker: it should get initial state from state_storage. ... ok
test_excluded_callable_and_types_exceptions (tests.CircuitBreakerTestCase)
CircuitBreaker: it should allow a mix of exclusions that includes both filter functions and types. ... ok
test_excluded_callable_exceptions (tests.CircuitBreakerTestCase)
CircuitBreaker: it should ignore specific exceptions that return true from a filtering callable. ... ok
test_excluded_exceptions (tests.CircuitBreakerTestCase)
CircuitBreaker: it should ignore specific exceptions. ... ok
test_fail_max_setter (tests.CircuitBreakerTestCase)
CircuitBreaker: it should allow the user to set a new value for ... ok
test_failed_call_after_timeout (tests.CircuitBreakerTestCase)
CircuitBreaker: it should half-open the circuit after timeout. ... ok
test_failed_call_when_halfopen (tests.CircuitBreakerTestCase)
CircuitBreaker: it should open the circuit when a call fails in ... ok
test_failure_count_not_reset_during_creation (tests.CircuitBreakerTestCase) ... ok
test_generator (tests.CircuitBreakerTestCase)
CircuitBreaker: it should inspect generator values. ... ok
test_name (tests.CircuitBreakerTestCase)
CircuitBreaker: it should allow an optional name to be set and ... ok
test_new_with_custom_excluded_exceptions (tests.CircuitBreakerTestCase)
CircuitBreaker: it should support a custom list of excluded ... ok
test_new_with_custom_fail_max (tests.CircuitBreakerTestCase)
CircuitBreaker: it should support a custom maximum number of ... ok
test_new_with_custom_reset_timeout (tests.CircuitBreakerTestCase)
CircuitBreaker: it should support a custom reset timeout value. ... ok
test_no_tornado_raises (tests.CircuitBreakerTestCase) ... ok
test_notify_called_on_state_change (tests.CircuitBreakerTestCase) ... ok
test_notify_not_called_on_init (tests.CircuitBreakerTestCase) ... ok
test_one_failed_call (tests.CircuitBreakerTestCase)
CircuitBreaker: it should keep the circuit closed after a few ... ok
test_one_successful_call_after_failed_call (tests.CircuitBreakerTestCase)
CircuitBreaker: it should keep the circuit closed after few mixed ... ok
test_remove_excluded_exception (tests.CircuitBreakerTestCase)
CircuitBreaker: it should allow the user to remove an excluded ... ok
test_remove_listener (tests.CircuitBreakerTestCase)
CircuitBreaker: it should allow the user to remove a listener. ... ok
test_reset_timeout_setter (tests.CircuitBreakerTestCase)
CircuitBreaker: it should allow the user to set a new value for ... ok
test_several_failed_calls_setting_absent (tests.CircuitBreakerTestCase)
CircuitBreaker: it should open the circuit after many failures. ... ok
test_state_opened_at_not_reset_during_creation (tests.CircuitBreakerTestCase) ... ok
test_successful_after_timeout (tests.CircuitBreakerTestCase)
CircuitBreaker: it should close the circuit when a call succeeds ... ok
test_successful_call (tests.CircuitBreakerTestCase)
CircuitBreaker: it should keep the circuit closed after a successful ... ok
test_successful_call_when_halfopen (tests.CircuitBreakerTestCase)
CircuitBreaker: it should close the circuit when a call succeeds in ... ok
test_throw_new_error_on_trip_false (tests.CircuitBreakerTestCase)
CircuitBreaker: it should throw the original exception ... ok
test_throw_new_error_on_trip_true (tests.CircuitBreakerTestCase)
CircuitBreaker: it should throw a CircuitBreakerError exception ... ok
test_traceback_in_circuitbreaker_error (tests.CircuitBreakerTestCase)
CircuitBreaker: it should open the circuit after many failures. ... ok
test_transition_events (tests.CircuitBreakerTestCase)
CircuitBreaker: it should call the appropriate functions on every ... ok
test_fail_max_thread_safety (tests.CircuitBreakerThreadsTestCase)
CircuitBreaker: it should not allow more failed calls than ... ok
test_fail_thread_safety (tests.CircuitBreakerThreadsTestCase)
CircuitBreaker: it should compute a failed call atomically to ... ok
test_half_open_thread_safety (tests.CircuitBreakerThreadsTestCase)
CircuitBreaker: it should allow only one trial call when the ... ok
test_success_thread_safety (tests.CircuitBreakerThreadsTestCase)
CircuitBreaker: it should compute a successful call atomically ... ok

----------------------------------------------------------------------
Ran 74 tests in 6.386s

OK
(9:37:23) ~/pybreaker #: ```
danielfm commented 2 years ago

Thanks for the contribution!