Dealing with not so exceptional exceptions
-
Upload
charles-desneuf -
Category
Technology
-
view
73 -
download
0
Transcript of Dealing with not so exceptional exceptions
Dealing with not so exceptional exceptions
Use case● Newsletter registration service talking to a partner
● Have to block process when failing in some cases
● We don’t really care if it failed in some other cases
● Partner throws an exception when we don’t have enough funds to register a new
function exception_handler($exception) {
$logger->critical($exception);
}
set_exception_handler('exception_handler');
function exception_handler($exception) {
$logger->critical($exception);
}
set_exception_handler('exception_handler');
��
// app.log
[2017-07-19 08:11:17] app.CRITICAL: Something really bad occurred {} []
// app.log
[2017-07-19 08:11:17] app.CRITICAL: Something really bad occurred {} []
��
�
$logger->critical($exception);
Application -> logs
// class NewsletterService
public function register($email) {
// throw an Exception ?
}
// class MemberService
public function register($email, $password) {
// …
$this->newsletterService->register($email);
}
��
// app.log
[2017-07-19 11:12:36] app.CRITICAL: Not enough funds {} []
// app.log
[2017-07-19 11:12:36] app.CRITICAL: Not enough funds {} []
��
�
��
// class MemberService
public function register($email, $password) {
// …
try {
$this->newsletterService->register($email);
}
catch(\Exception $exception)
{}
}
��
// app.log
��
��
// MemberService::register
try {
$this->newsletterService->register($email);
}
catch(\Exception $exception)
{
$this->logger->critical($exception);
}
��
// app.log
[2017-07-19 03:35:17] app.CRITICAL: Not enough funds {} []
// app.log
[2017-07-19 03:35:17] app.CRITICAL: Not enough funds {} []
�
��
�
��
// class NewsletterService
/**
* @throw CouldNotRegisterToNewsletterException
*/
public function register($email) {
// throw an Exception ?
}
// NewsletterService::register
try { // … }
catch(AKnownException $exception) {
throw new CouldNotRegisterToNewsletterException(
sprintf(‘Could not register %s to newsletter’, $email),
0,
$exception);
}
}
// NewsletterService::register
try { // … }
catch(AKnownException $exception) {
throw new CouldNotRegisterToNewsletterException(
sprintf(‘Could not register %s to newsletter’, $email),
0,
$exception);
}
}
// NewsletterService::register
try { // … }
catch(AKnownException $exception) {
throw new CouldNotRegisterToNewsletterException(
sprintf(‘Could not register %s to newsletter’, $email),
0,
$exception);
}
}
// NewsletterService::register
try { // … }
catch(AKnownException $exception) {
throw new CouldNotRegisterToNewsletterException(
sprintf(‘Could not register %s to newsletter’, $email),
0,
$exception);
}
}
// MemberService::register
try {
$this->newsletterService->register($email);
}
catch(CouldNotRegisterToNewsletterException $exception)
{
$this->logger->warning($exception);
}
��
// app.log
[2017-07-19 03:35:17] app.WARNING: Not enough funds {} []
// app.log
[2017-07-19 03:35:17] app.WARNING: Not enough funds {} []
�
throw new CouldNotRegisterToNewsletterException(
...,
...,
$exception);
Context -> Context
Drawback● Repeat try/catch block each time a fail safe registration is needed
Tell, don’t ask
// class NewsletterService
/**
* @throw CouldNotRegisterToNewsletterException
*/
public function register($email) {
// throw an Exception ?
}
// class NewsletterService
public function registerFailSafe($email) {
try {
$this->register($email);
}
catch(AKnownException $exception) {
$this->logger->warning($exception);
}
}
// class MemberService
public function register($email, $password) {
// …
$this->newsletterService->registerFailSafe($email);
}
�
��
��
// app.log
[2017-07-19 22:35:17] app.WARNING: Not enough funds {} []
// app.log
[2017-07-19 22:35:17] app.WARNING: Not enough funds {} []
��
Drawback● Trust the implementer of NewsletterService to log properly
● No log showing easily that registration to newsletter failed
Takeaways● Catching an exception is a translation mechanism
● You (probably) mustn’t catch \Exception
● Never hide an error in the system
● Think about the log level and what it means