Javascript decorator that handles unhandled promise rejection - typescript-decorator

can someone share a way to build a decorator, which will wrap each method of a class with try-catch block, so all method errors are handled the same way while decreasing the amount of code boilerplate? The final implementation should look like this:
#ExceptionHandler()
export class MiserableClass {
public miserableMethod(){
throw new Error('Error in miserableMethod()')
}
}
Exception handler should contain logic like logging the error to console, logging error to Sentry, etc.

Related

Service #Transactional exception translation

I have a web service with an operation that looks like
public Result checkout(String id) throws LockException;
implemented as:
#Transactional
public Result checkout(String id) throws LockException {
someDao.acquireLock(id); // ConstraintViolationException might be thrown on commit
Data data = otherDao.find(id);
return convert(data);
}
My problem is that locking can only fail on transaction commit which occurs outside of my service method so I have no opportunity to translate the ConstraintViolationException to my custom LockException.
Option 1
One option that's been suggested is to make the service delegate to another method that's #Transactional. E.g.
public Result checkout(String id) throws LockException {
try {
return someInternalService.checkout(id);
}
catch (ConstraintViolationException ex) {
throw new LockException();
}
}
...
public class SomeInternalService {
#Transactional
public Result checkout(String id) {
someDao.acquireLock(id);
Data data = otherDao.find(id);
return convert(data);
}
}
My issues with this are:
There is no reasonable name for the internal service that isn't already in use by the external service since they are essentially doing the same thing. This seems like an indicator of bad design.
If I want to reuse someInternalService.checkout in another place, the contract for that is wrong because whatever uses it can get a ConstraintViolationException.
Option 2
I thought of maybe using AOP to put advice around the service that translates the exception. This seems wrong to me though because checkout needs to declare that it throws LockException for clients to use it, but the actual service will never throw this and it will instead be thrown by the advice. There's nothing to prevent someone in the future from removing throws LockException from the interface because it appear to be incorrect.
Also, this way is harder to test. I can't write a JUnit test that verifies an exception is thrown without creating a spring context and using AOP during the tests.
Option 3
Use manual transaction management in checkout? I don't really like this because everything else in the application is using the declarative style.
Does anyone know the correct way to handle this situation?
There's no one correct way.
A couple more options for you:
Make the DAO transactional - that's not great, but can work
Create a wrapping service - called Facade - whose job it is to do exception handling/wrapping around the transactional services you've mentioned - this is a clear separation of concerns and can share method names with the real lower-level service

unit test all permutations or start publicly exposing more? Where's the line?

I know that there have been a few posts about this already but I wanted to post one with a concrete example to focus on the gray areas you face when choosing between testing private/internal methods and refactoring into a public class.
Say I have a simple class I want to test that has some internal code refactored into a private or internal method.
Example:
public class Guy
{
public void DoSomeWork()
{
try
{
//do some work
}
catch(Exception e)
{
LogError(e.Message);
}
try
{
//do some more work
}
catch(SomeSpecificException e)
{
LogError(e.Message);
}
}
private void LogError(string message)
{
//if logging folder doesn't exist, create it
//create a log file
//log the message
}
}
Most people would advise that I should take the error logging logic out and put it in a class marked public because it's starting to be complex enough to stand on its own, but the assembly's internal error logging logic shouldn't be exposed publicly--it's not a logging assembly.
If I don't do that, then every time I have code that could call LogError(), I need to have subsequent tests that retest all of the internal logic for LogError(). That quickly becomes oppressive.
I also understand I can mark the method as internal and make it visible to a testing assembly but it's not very "pure."
What sort of guidelines can I abide by in this type of situation?
but the assembly's internal error logging logic shouldn't be exposed publicly
That's true. It can be internal and tested as such. But this
private void LogError(string message)
{
//if logging folder doesn't exist, create it
//create a log file
//log the message
}
Calls for a separate component. Create folder? Create file? Whatever DoSomeWork does, it should have nothing to do with creating log file internals. All it should require is simple "log this message"-feature. Files, folders, formats -- it's all specific to logging component and shouldn't leak to any other.
Your sample code is perfect example of single responsibility principle violation. Extracting logging to fix it solves your testing issues completely.
One possible way to handle this is instead of logging the error in your DoSomeWork method, you simply raise the error, and let it get handled upstream. Then you test that the error was raised, and for the purposes of testing the DoSomeWork method, you don't care what happens after that.
Whether or not this is a good idea depends a lot on how the rest of your program is structured, but having LogError sprinkled all over the place may indicate you need a broader error handling strategy that this approach requires.
UPDATE:
public void DoSomeWork() {
try {
WorkPartA()
}
catch(Exception e) {
LogError(e.Message)
}
try {
WorkPartB()
}
catch(SomeSpecificException e) {
LogError(e.Message)
}
}
public void WorkPartA() {
//do some work
}
public void WorkPartB() {
//do some more work
}
As a response to your comment below, the problem might be that you need to break up your code into smaller pieces. This approach allows you to test raising the exception within WorkPartA() and WorkPartB() individually, while still allowing the process to run if WorkPartA fails. As far as testing DoSomeWork() in this case, I might not even bother. There's a high probability it would be a very low-value test anyway.

How to trigger `error` action *outside* of a transition

I'm looking to implement some consistent error handling in my app through the error action. The problem I've run into is that it is only triggered when an exception is raised while in a transition, and not, for example, in a plain saveModelInResponseToUserClick action on a route.
I can sort of get something to work with the following, but it's a hack:
Ember.onerror = function(error) {
MyApp.__container__.lookup('router:main').send('handleError')
}
With that, I could have different error-handling logic in differently-nested routes.
EDIT: Another issue with using the method above is when an error occurs before the app has fully transitioned into its first route - another exception is raised in that case and everything blows up.
Is there a different approach I can take with this?
As you said, the error action will only trigger while in transition.
For errors that may arise from an action, you could try using the following:
Ember.RSVP.on('error', function(error) {
// handle error
}
This will catch ANY error that occurs as a result of a promise in your app. You can access the "error" object inside the function, which will give you some detail as to what exactly went wrong, particularly the "responseText" attribute. The code itself goes in your app.js file.
Ember docs on this: http://emberjs.com/guides/understanding-ember/debugging/#toc_errors-within-an-code-rsvp-promise-code

PHPUnit Testing Exceptions for Laravel Resource Controllers

Is it possible to test Exceptions with Laravel resource controllers? Every time I try to do the following:
/**
* #expectedException Exception
* #expectedExceptionMessage Just testing this out
*/
public function testMyPost() {
$response = $this->call('POST', '/api/myapi/', array('testing' => 1));
}
I get:
Failed asserting that exception of type "Exception" is thrown.
I've tried this with \Exception and Exception.
In my resource controller I have:
public function store() {
throw new \Exception('Just for testing!');
}
Does anyone has any idea of I can test Exceptions? I've also tried using:
$this->setExpectedException('InvalidArgumentException');
The problem is as hannesvdvreken states; the exception is caught. An easy work-around is to tell Laravels errort/exception handler, that when we are testing, we just want our exceptions thrown.
That could look something like this:
// If we are testing, just throw the exception.
if (App::environment() == 'testing') {
throw $e;
}
For Laravel 5, this should go in the render method in app/Exceptions/Handler.php
For Laravel 4, this should go in app/start/global.php within:
App::error(function(Exception $exception, $code)...
Don't focus on the notation of #expectedException. The problem is the Exception is catched somewhere. Maybe with the default App::error(function(Exception) {... inside the app/start/global.php file.
Or maybe you did a try catch somewhere. Try making a custom Exception that does not get catched by a generic exception catcher that catches everything that's inherited from Exception.

Dll's, Message Boxes, and Unit Testing

Ok... I am working on a dll that manages some configured settings (I won't bore you with the details and reasoning here as that doesn't apply). I have a class for referencing assemblies to use to interface with this system. this class has a Load() method. When there are read or validation errors, I currently have it showing a message box. I didn't feel it should be the responsibility of the referencing assembly to manage this? Or am I wrong? Currently this is creating havoc with creating unit tests, so I'm considering adding a property to suppress messages, but still allow the exceptions to be thrown. I read on one other SO posting where someone was recommended to use IoC and a dialog result helper class. The illustration was with Constructor Injection... but that would again put that responsibility into the hands of the referencing assembly. What's best practice in this case?
Personally, I think you're wrong - sorry. The DLL's responsibility is to notify of the errors, the calling code's responsibility is to determine what to do with that notification. If it's a GUI, then it can show a dialog box. If it's a unit test, it can test appropriately. If it's a website, it can write the notification out in HTML to the user. If it's a service of some sort, it can log it. And so on.
You can use a delegate to send messages to be handled elsewhere. I have made an example below using a unittest:
public delegate void ErrorHandlingDelegate(Exception exception); //The delegate
public class AsseblymRefClass //Your class doing the business logic
{
public void DoStuff(ErrorHandlingDelegate errorHandling) //Passing the delegate as argument
{
try
{
//Do your stuff
throw new Exception();
}
catch (Exception ex)
{
errorHandling(ex); //Calling the delegate
}
}
}
//Another class that can handle the error through its method 'HandleErrorsFromOtherClass()'
public class ErrorHandlingClass
{
public void HandleErrorsFromOtherClass(Exception exception)
{
MessageBox.Show(exception.Message);
}
}
[Test]
public void testmethod() //The test that creates your class, and a class for the errorhandling, and connects the two
{
ErrorHandlingClass errorHandling = new ErrorHandlingClass();
AsseblymRefClass assemblyRef = new AsseblymRefClass();
assemblyRef.DoStuff(errorHandling.HandleErrorsFromOtherClass);
}
Any method that fits the delegate can be used. Thus, you can replace your production code, with something that doesn't show a messagebox when unit testing.