Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Clean Error Handling

Clean Error Handling

Error handling important because things can go wrong. Therefore as a developer, we have to make sure our code acts properly in such situations. This talk covers things that will help you handle errors in clean and elegant way in your code.
Provided sample code fragments use Java.

Avatar for Natig Babayev

Natig Babayev

March 06, 2019

Other Decks in Programming

Transcript

  1. public void authorize(String pin) { pinCode.verify(pin); int verificationResult = pinCode.lastError();

    if (verificationResult == PinCode.ERROR_NONE) { paymentVerifier.acceptLastPayment(); int result = paymentVerifier.lastError(); if (result == PaymentVerifier.ERROR_NONE) { view.show("Payment has been processed"); } else if (result == PaymentVerifier.ERROR_EXPIRED) { view.show("Payment request has been expired."); } else { view.show("Unknown error"); } } else if (verificationResult == PinCode.ERROR_NOT_SET) { view.show("You have to set PIN first."); } else if (verificationResult == PinCode.ERROR_INCORRECT_PIN) { view.show("PIN is not correct. Try again."); } else { view.show("Too many wrong attempts"); } }
  2. public void authorize(String pin) { pinCode.verify(pin); int verificationResult = pinCode.lastError();

    if (verificationResult == PinCode.ERROR_NONE) { paymentVerifier.acceptLastPayment(); int result = paymentVerifier.lastError(); if (result == PaymentVerifier.ERROR_NONE) { view.show("Payment has been processed"); } else if (result == PaymentVerifier.ERROR_EXPIRED) { view.show("Payment request has been expired."); } else { view.show("Unknown error"); } } else if (verificationResult == PinCode.ERROR_NOT_SET) { view.show("You have to set PIN first."); } else if (verificationResult == PinCode.ERROR_INCORRECT_PIN) { view.show("PIN is not correct. Try again."); } else { view.show("Too many wrong attempts"); } }
  3. public void authorize(String pin) { pinCode.verify(pin); int verificationResult = pinCode.lastError();

    if (verificationResult == PinCode.ERROR_NONE) { paymentVerifier.acceptLastPayment(); int result = paymentVerifier.lastError(); if (result == PaymentVerifier.ERROR_NONE) { view.show("Payment has been processed"); } else if (result == PaymentVerifier.ERROR_EXPIRED) { view.show("Payment request has been expired."); } else { view.show("Unknown error"); } } else if (verificationResult == PinCode.ERROR_NOT_SET) { view.show("You have to set PIN first."); } else if (verificationResult == PinCode.ERROR_INCORRECT_PIN) { view.show("PIN is not correct. Try again."); } else { view.show("Too many wrong attempts"); } }
  4. public void authorize(String pin) { pinCode.verify(pin); int verificationResult = pinCode.lastError();

    if (verificationResult == PinCode.ERROR_NONE) { paymentVerifier.acceptLastPayment(); int result = paymentVerifier.lastError(); if (result == PaymentVerifier.ERROR_NONE) { view.show("Payment has been processed"); } else if (result == PaymentVerifier.ERROR_EXPIRED) { view.show("Payment request has been expired."); } else { view.show("Unknown error"); } } else if (verificationResult == PinCode.ERROR_NOT_SET) { view.show("You have to set PIN first."); } else if (verificationResult == PinCode.ERROR_INCORRECT_PIN) { view.show("PIN is not correct. Try again."); } else { view.show("Too many wrong attempts"); } }
  5. public void authorize(String pin) { pinCode.verify(pin); int verificationResult = pinCode.lastError();

    if (verificationResult == PinCode.ERROR_NONE) { paymentVerifier.acceptLastPayment(); int result = paymentVerifier.lastError(); if (result == PaymentVerifier.ERROR_NONE) { view.show("Payment has been processed"); } else if (result == PaymentVerifier.ERROR_EXPIRED) { view.show("Payment request has been expired."); } else { view.show("Unknown error"); } } else if (verificationResult == PinCode.ERROR_NOT_SET) { view.show("You have to set PIN first."); } else if (verificationResult == PinCode.ERROR_INCORRECT_PIN) { view.show("PIN is not correct. Try again."); } else { view.show("Too many wrong attempts"); } }
  6. public void authorize(String pin) { pinCode.verify(pin); int verificationResult = pinCode.lastError();

    if (verificationResult == PinCode.ERROR_NONE) { paymentVerifier.acceptLastPayment(); int result = paymentVerifier.lastError(); if (result == PaymentVerifier.ERROR_NONE) { view.show("Payment has been processed"); } else if (result == PaymentVerifier.ERROR_EXPIRED) { view.show("Payment request has been expired."); } else { view.show("Unknown error"); } } else if (verificationResult == PinCode.ERROR_NOT_SET) { view.show("You have to set PIN first."); } else if (verificationResult == PinCode.ERROR_INCORRECT_PIN) { view.show("PIN is not correct. Try again."); } else { view.show("Too many wrong attempts"); } }
  7. public void authorize(String pin) { pinCode.verify(pin); int verificationResult = pinCode.lastError();

    if (verificationResult == PinCode.ERROR_NONE) { paymentVerifier.acceptLastPayment(); int result = paymentVerifier.lastError(); if (result == PaymentVerifier.ERROR_NONE) { view.show("Payment has been processed"); } else if (result == PaymentVerifier.ERROR_EXPIRED) { view.show("Payment request has been expired."); } else { view.show("Unknown error"); } } else if (verificationResult == PinCode.ERROR_NOT_SET) { view.show("You have to set PIN first."); } else if (verificationResult == PinCode.ERROR_INCORRECT_PIN) { view.show("PIN is not correct. Try again."); } else { view.show("Too many wrong attempts"); } }
  8. public void authorize(String pin) { pinCode.verify(pin); int verificationResult = pinCode.lastError();

    if (verificationResult == PinCode.ERROR_NONE) { paymentVerifier.acceptLastPayment(); int result = paymentVerifier.lastError(); if (result == PaymentVerifier.ERROR_NONE) { view.show("Payment has been processed"); } else if (result == PaymentVerifier.ERROR_EXPIRED) { view.show("Payment request has been expired."); } else { view.show("Unknown error"); } } else if (verificationResult == PinCode.ERROR_NOT_SET) { view.show("You have to set PIN first."); } else if (verificationResult == PinCode.ERROR_INCORRECT_PIN) { view.show("PIN is not correct. Try again."); } else { view.show("Too many wrong attempts"); } }
  9. public void authorize(String pin) { try { pinCode.verify(pin); // throws

    exception paymentVerifier.acceptLastPayment(); // throws exception } catch (Throwable throwable) { handleErrors(throwable); } }
  10. public void authorize(String pin) { try { pinCode.verify(pin); // throws

    exception paymentVerifier.acceptLastPayment(); // throws exception } catch (Throwable throwable) { handleErrors(throwable); } } Easier to read and understand what method is supposed to do
  11. public void authorize(String pin) { try { pinCode.verify(pin); // throws

    exception paymentVerifier.acceptLastPayment(); // throws exception } catch (Throwable throwable) { handleErrors(throwable); } } Easier to read and understand what method is supposed to do Concerns are separated
  12. “Software entities (classes, modules, functions, etc.) should be open for

    extension, but closed for modification.” Open/Closed Principle
  13. Use Exceptions Rather Than Return Codes Write Your Try-Catch-Finally Statement

    First Use Unchecked Exceptions Provide Context with Exceptions
  14. ✅ Failed operation & the type of failure Informative error

    messages ❌ Sensitive data ✅ Values of parameters and fields
  15. Use Exceptions Rather Than Return Codes Write Your Try-Catch-Finally Statement

    First Use Unchecked Exceptions Provide Context with Exceptions Define Exception Classes in Terms of a Caller’s Needs
  16. try { paymentsAPI.getPayments(); } catch (HttpException e) { view.show("Request failed:

    " + e.code()); } catch (SocketTimeoutException e) { view.show("Request failed: 504"); } catch (ConnectException e) { view.show("Request failed: 503"); } catch (InternalError e) { view.show("Request failed: 500"); } catch (Exception e) { view.show("Request failed: 418"); }
  17. public class PaymentsApiWrapper { private final PaymentsAPI paymentsAPI; public PaymentsApiWrapper(PaymentsAPI

    paymentsAPI) { this.paymentsAPI = paymentsAPI; } public List<Payment> getPayments() { try { return paymentsAPI.getPayments(); } catch (HttpException e) { throw new PaymentsApiException("getPayments request failed: " + e.code()); } catch (SocketTimeoutException e) { throw new PaymentsApiException("getPayments request failed: 504"); } catch (ConnectException e) { throw new PaymentsApiException("getPayments request failed: 503"); } catch (InternalError e) { throw new PaymentsApiException("getPayments request failed: 500"); } catch (Exception e) { throw new PaymentsApiException("getPayments request failed: 418"); } } }
  18. Use Exceptions Rather Than Return Codes Write Your Try-Catch-Finally Statement

    First Use Unchecked Exceptions Provide Context with Exceptions Define Exception Classes in Terms of a Caller’s Needs Define the Normal Flow
  19. Create a class or configure an object so that it

    handles a special case for you.
  20. Use Exceptions Rather Than Return Codes Write Your Try-Catch-Finally Statement

    First Use Unchecked Exceptions Provide Context with Exceptions Define Exception Classes in Terms of a Caller’s Needs Define the Normal Flow Don't Return Null
  21. private void retrievePendingPayments() { List<Payment> payments = payments.getPendingPayments(); if (payments

    != null && payments.size() > 0) { view.displayPendingPayments(payments); } }
  22. Use Exceptions Rather Than Return Codes Write Your Try-Catch-Finally Statement

    First Use Unchecked Exceptions Provide Context with Exceptions Define Exception Classes in Terms of a Caller’s Needs Define the Normal Flow Don't Return Null Don't Pass Null
  23. public class PinCode { ... public void verify(@NotNull String pin)

    { if (pin == null) throw new NullPointerException("pin == null"); ... } .. }
  24. public class PinCode { ... public void verify(@NotNull String pin)

    { if (pin == null) throw new NullPointerException("pin == null"); ... } .. }
  25. public class PinCode { ... public void verify(@NotNull String pin)

    { if (pin == null) throw new NullPointerException("pin == null"); ... } .. }