How to fix “'throw' of exception caught locally”?












14















In this function that handles a REST API call, any of the called functions to handle parts of the request might throw an error to signal that an error code should be sent as response. However, the function itself might also discover an error, at which point it should jump into the exception handling block.



static async handleRequest(req) {
try {
let isAllowed = await checkIfIsAllowed(req);
if (!isAllowed) {
throw new ForbiddenException("You're not allowed to do that.");
}
let result = await doSomething(req); // can also raise exceptions
sendResult(result);
} catch(err) {
sendErrorCode(err);
}
}


Webstorm will underline the throw with the following message: 'throw' of exception caught locally. This inspection reports any instances of JavaScript throw statements whose exceptions are always caught by containing try statements. Using throw statements as a "goto" to change the local flow of control is likely to be confusing.



However, I'm not sure how to refactor the code to improve the situation.



I could copypaste the code from the catch block into the if check, but I believe this would make my code less readable and harder to maintain.



I could write a new function that does the isAllowed check and throws an exception if it doesn't succeed, but that seems to be sidestepping the issue, rather than fixing a design problem that Webstorm is supposedly reporting.



Are we using exceptions in a bad way, and that's why we're encountering this problem, or is the Webstorm error simply misguiding and should be disabled?










share|improve this question

























  • @matchish Hey - just noticed this bounty. I'm unsure what part of my answer you feel breaks DRY principles? The only thing I can think is the sendErrorCode - but it's not being repeated verbatim; in one place it's sending a very specific error from this block of code, in the more general catch it's sending a more general error that hasn't been coded for...?

    – James Thorpe
    Jan 17 at 15:23
















14















In this function that handles a REST API call, any of the called functions to handle parts of the request might throw an error to signal that an error code should be sent as response. However, the function itself might also discover an error, at which point it should jump into the exception handling block.



static async handleRequest(req) {
try {
let isAllowed = await checkIfIsAllowed(req);
if (!isAllowed) {
throw new ForbiddenException("You're not allowed to do that.");
}
let result = await doSomething(req); // can also raise exceptions
sendResult(result);
} catch(err) {
sendErrorCode(err);
}
}


Webstorm will underline the throw with the following message: 'throw' of exception caught locally. This inspection reports any instances of JavaScript throw statements whose exceptions are always caught by containing try statements. Using throw statements as a "goto" to change the local flow of control is likely to be confusing.



However, I'm not sure how to refactor the code to improve the situation.



I could copypaste the code from the catch block into the if check, but I believe this would make my code less readable and harder to maintain.



I could write a new function that does the isAllowed check and throws an exception if it doesn't succeed, but that seems to be sidestepping the issue, rather than fixing a design problem that Webstorm is supposedly reporting.



Are we using exceptions in a bad way, and that's why we're encountering this problem, or is the Webstorm error simply misguiding and should be disabled?










share|improve this question

























  • @matchish Hey - just noticed this bounty. I'm unsure what part of my answer you feel breaks DRY principles? The only thing I can think is the sendErrorCode - but it's not being repeated verbatim; in one place it's sending a very specific error from this block of code, in the more general catch it's sending a more general error that hasn't been coded for...?

    – James Thorpe
    Jan 17 at 15:23














14












14








14


1






In this function that handles a REST API call, any of the called functions to handle parts of the request might throw an error to signal that an error code should be sent as response. However, the function itself might also discover an error, at which point it should jump into the exception handling block.



static async handleRequest(req) {
try {
let isAllowed = await checkIfIsAllowed(req);
if (!isAllowed) {
throw new ForbiddenException("You're not allowed to do that.");
}
let result = await doSomething(req); // can also raise exceptions
sendResult(result);
} catch(err) {
sendErrorCode(err);
}
}


Webstorm will underline the throw with the following message: 'throw' of exception caught locally. This inspection reports any instances of JavaScript throw statements whose exceptions are always caught by containing try statements. Using throw statements as a "goto" to change the local flow of control is likely to be confusing.



However, I'm not sure how to refactor the code to improve the situation.



I could copypaste the code from the catch block into the if check, but I believe this would make my code less readable and harder to maintain.



I could write a new function that does the isAllowed check and throws an exception if it doesn't succeed, but that seems to be sidestepping the issue, rather than fixing a design problem that Webstorm is supposedly reporting.



Are we using exceptions in a bad way, and that's why we're encountering this problem, or is the Webstorm error simply misguiding and should be disabled?










share|improve this question
















In this function that handles a REST API call, any of the called functions to handle parts of the request might throw an error to signal that an error code should be sent as response. However, the function itself might also discover an error, at which point it should jump into the exception handling block.



static async handleRequest(req) {
try {
let isAllowed = await checkIfIsAllowed(req);
if (!isAllowed) {
throw new ForbiddenException("You're not allowed to do that.");
}
let result = await doSomething(req); // can also raise exceptions
sendResult(result);
} catch(err) {
sendErrorCode(err);
}
}


Webstorm will underline the throw with the following message: 'throw' of exception caught locally. This inspection reports any instances of JavaScript throw statements whose exceptions are always caught by containing try statements. Using throw statements as a "goto" to change the local flow of control is likely to be confusing.



However, I'm not sure how to refactor the code to improve the situation.



I could copypaste the code from the catch block into the if check, but I believe this would make my code less readable and harder to maintain.



I could write a new function that does the isAllowed check and throws an exception if it doesn't succeed, but that seems to be sidestepping the issue, rather than fixing a design problem that Webstorm is supposedly reporting.



Are we using exceptions in a bad way, and that's why we're encountering this problem, or is the Webstorm error simply misguiding and should be disabled?







javascript node.js rest exception-handling async-await






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Oct 30 '17 at 12:57







cib

















asked Oct 30 '17 at 12:48









cibcib

724918




724918













  • @matchish Hey - just noticed this bounty. I'm unsure what part of my answer you feel breaks DRY principles? The only thing I can think is the sendErrorCode - but it's not being repeated verbatim; in one place it's sending a very specific error from this block of code, in the more general catch it's sending a more general error that hasn't been coded for...?

    – James Thorpe
    Jan 17 at 15:23



















  • @matchish Hey - just noticed this bounty. I'm unsure what part of my answer you feel breaks DRY principles? The only thing I can think is the sendErrorCode - but it's not being repeated verbatim; in one place it's sending a very specific error from this block of code, in the more general catch it's sending a more general error that hasn't been coded for...?

    – James Thorpe
    Jan 17 at 15:23

















@matchish Hey - just noticed this bounty. I'm unsure what part of my answer you feel breaks DRY principles? The only thing I can think is the sendErrorCode - but it's not being repeated verbatim; in one place it's sending a very specific error from this block of code, in the more general catch it's sending a more general error that hasn't been coded for...?

– James Thorpe
Jan 17 at 15:23





@matchish Hey - just noticed this bounty. I'm unsure what part of my answer you feel breaks DRY principles? The only thing I can think is the sendErrorCode - but it's not being repeated verbatim; in one place it's sending a very specific error from this block of code, in the more general catch it's sending a more general error that hasn't been coded for...?

– James Thorpe
Jan 17 at 15:23












5 Answers
5






active

oldest

votes


















19














You're checking for something and throwing an exception if isAllowed fails, but you know what to do in that situation - call sendErrorCode. You should throw exceptions to external callers if you don't know how to handle the situation - ie in exceptional circumstances.



In this case you already have a defined process of what to do if this happens - just use it directly without the indirect throw/catch:



static async handleRequest(req) {
try {
let isAllowed = await checkIfIsAllowed(req);
if (!isAllowed) {
sendErrorCode("You're not allowed to do that.");
return;
}
let result = await doSomething(req); // can also raise exceptions
sendResult(result);
} catch(err) {
sendErrorCode(err);
}
}



I could copypaste the code from the catch block into the ifcheck, but I believe this would make my code less readable and harder to maintain.




On the contrary, as above, I would expect this to be the way to handle this situation.






share|improve this answer





















  • 1





    "You should throw exceptions to external callers if you don't know how to handle the situation - ie in exceptional circumstances." If that's true, that explains the issue. However, that means we're using exceptions wrong in the entire project, not just this function. Since there are no other answers, I'll accept this one.

    – cib
    Nov 2 '17 at 9:09



















0














Answer of James Thorpe has one disadvantage on my opinion. It's not DRY, in both cases when you call sendError you handle Exceptions. Let's imagine we have many lines of code with logic like this where Exception can be thrown. I think it can be better.



This is my solution



async function doSomethingOnAllowedRequest(req) {
let isAllowed = await checkIfIsAllowed(req);
if (!isAllowed) {
throw new ForbiddenException("You're not allowed to do that.");
}
doSomething(req);
}
static async handleRequest(req) {
try {
let result = await doSomethingOnAllowedRequest(req);
sendResult(result);
} catch(err) {
sendErrorCode(err);
}
}





share|improve this answer
























  • It is DRY, in that if you're not allowed to do the action, you're sending a very specific error message. The catch is there for all other exceptions. IMO you're just moving the "don't use exceptions for flow logic control" into another method here. Throwing an exception is not cheap (computationally) compared to not throwing either - if you can avoid doing so, far better to not do it.

    – James Thorpe
    Jan 17 at 16:49











  • I prefer readability to performance. IMO It's not just moving. doSomething also can throw Exception, but I don't think we can say we use exception for flow control in this case. You can doSomething only on allowed request if it not allowed you should throw the exception.

    – matchish
    Jan 17 at 17:52



















0














There are good answers to the question "Why not use exceptions as normal flow control?" here.



The reason not to throw an exception that you will catch locally is that you locally know how to handle that situation, so it is, by definition, not exceptional.



@James Thorpe's answer looks good to me, but @matchish feels it violates DRY. I say that in general, it does not. DRY, which stands for Don't Repeat Yourself, is defined by the people who coined the phrase as "Every piece of knowledge must have a single, unambiguous, authoritative representation within a system". As applied to writing software code, it is about not repeating complex code.



Practically any code that is said to violate DRY is said to be "fixed" by extracting the repeated code into a function and then calling that function from the places it was previously repeated. Having multiple parts of your code call sendErrorCode is the solution to fixing a DRY problem. All of the knowledge of what to do with the error is in one definitive place, namely the sendErrorCode function.



I would modify @James Thorpe's answer slightly, but it is more of a quibble than a real criticism, which is that sendErrorCode should be receiving exception objects or strings but not both:



static async handleRequest(req) {
try {
let isAllowed = await checkIfIsAllowed(req);
if (!isAllowed) {
sendErrorCode(new ForbiddenException("You're not allowed to do that."));
return;
}
let result = await doSomething(req); // can also raise exceptions
sendResult(result);
} catch(err) {
sendErrorCode(err);
}
}


The larger question is what is the likelihood of the error and is it appropriate to treat !isAllowed as an exception. Exceptions are meant to handle unusual or unpredictable situations. I would expect !isAllowed to be a normal occurrence that should be handled with logic specific to that situation, unlike, say, a sudden inability to query the database that has the answer to the isAllowed question.



@matchish's proposed solution changes the contract of doSomethingOnAllowedRequest from something that will never throw an exception to something that will routinely throw an exception, placing the burden of exception handling on all of its callers. This is likely to cause a violation of DRY by causing multiple callers to have repetitions of the same error handling code, so in the abstract I do not like it. In practice, it would depend on the overall situation, such as how many callers are there and do they, in fact, share the same response to errors.






share|improve this answer
























  • What if you need to log errors? You should modify two lines of code, that's why I think it's not DRY.

    – matchish
    Jan 21 at 8:11











  • You write !isAllowed is not unpredictable situation, but I see ForbiddenException in your code. handleRequest created for to do something useful, and when we can't do it I think it's normal to throw the exception. For me sendErrorCode looks like throwing an exception to frontend

    – matchish
    Jan 21 at 8:20













  • @matchish "What if you need to log errors?" The !isAllowed isn't neccessarily an error/exception as far as this code is concerned (it's a handled use case), so no need to log it. At this point though, we're debating code for which we don't know the underlying semantics and use case of such things, and it's far removed from the original purpose of this Q&A.

    – James Thorpe
    Jan 21 at 9:07











  • I'm talking not about logging, it can be anything else. You have two pieces of code that will need to be changed if you need not only sendErrorCode. IMO It's not DRY

    – matchish
    Jan 21 at 9:38






  • 1





    @matchish how is logging errors in what is uniquely error handling code (sendErrorCode) more of a violation of SRP than logging errors in code whose job is to handle requests?

    – Old Pro
    Jan 23 at 7:14



















0





+50









Since this is not a blocking error, but only an IDE recommendation, then the question should be viewed from two sides.



The first side is performance. If this is a bottleneck and it is potentially possible to use it with compilation or when transferring to new (not yet released) versions of nodejs, the presence of repetitions is not always a bad solution. It seems that the IDE hints precisely in this case and that such a design can lead to poor optimization in some cases.



The second side is the code design. If it will make the code more readable and simplify the work for other developers - keep it. From this point of view, solutions have already been proposed above.






share|improve this answer

































    -3














    This could give you some tips, maybe that can be the cause(not sure if relevant).
    Catch statement does not catch thrown error



    "
    The reason why your try catch block is failing is because an ajax request is asynchronous. The try catch block will execute before the Ajax call and send the request itself, but the error is thrown when the result is returned, AT A LATER POINT IN TIME.



    When the try catch block is executed, there is no error. When the error is thrown, there is no try catch. If you need try catch for ajax requests, always put ajax try catch blocks inside the success callback, NEVER outside of it."






    share|improve this answer























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f47015693%2fhow-to-fix-throw-of-exception-caught-locally%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      5 Answers
      5






      active

      oldest

      votes








      5 Answers
      5






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      19














      You're checking for something and throwing an exception if isAllowed fails, but you know what to do in that situation - call sendErrorCode. You should throw exceptions to external callers if you don't know how to handle the situation - ie in exceptional circumstances.



      In this case you already have a defined process of what to do if this happens - just use it directly without the indirect throw/catch:



      static async handleRequest(req) {
      try {
      let isAllowed = await checkIfIsAllowed(req);
      if (!isAllowed) {
      sendErrorCode("You're not allowed to do that.");
      return;
      }
      let result = await doSomething(req); // can also raise exceptions
      sendResult(result);
      } catch(err) {
      sendErrorCode(err);
      }
      }



      I could copypaste the code from the catch block into the ifcheck, but I believe this would make my code less readable and harder to maintain.




      On the contrary, as above, I would expect this to be the way to handle this situation.






      share|improve this answer





















      • 1





        "You should throw exceptions to external callers if you don't know how to handle the situation - ie in exceptional circumstances." If that's true, that explains the issue. However, that means we're using exceptions wrong in the entire project, not just this function. Since there are no other answers, I'll accept this one.

        – cib
        Nov 2 '17 at 9:09
















      19














      You're checking for something and throwing an exception if isAllowed fails, but you know what to do in that situation - call sendErrorCode. You should throw exceptions to external callers if you don't know how to handle the situation - ie in exceptional circumstances.



      In this case you already have a defined process of what to do if this happens - just use it directly without the indirect throw/catch:



      static async handleRequest(req) {
      try {
      let isAllowed = await checkIfIsAllowed(req);
      if (!isAllowed) {
      sendErrorCode("You're not allowed to do that.");
      return;
      }
      let result = await doSomething(req); // can also raise exceptions
      sendResult(result);
      } catch(err) {
      sendErrorCode(err);
      }
      }



      I could copypaste the code from the catch block into the ifcheck, but I believe this would make my code less readable and harder to maintain.




      On the contrary, as above, I would expect this to be the way to handle this situation.






      share|improve this answer





















      • 1





        "You should throw exceptions to external callers if you don't know how to handle the situation - ie in exceptional circumstances." If that's true, that explains the issue. However, that means we're using exceptions wrong in the entire project, not just this function. Since there are no other answers, I'll accept this one.

        – cib
        Nov 2 '17 at 9:09














      19












      19








      19







      You're checking for something and throwing an exception if isAllowed fails, but you know what to do in that situation - call sendErrorCode. You should throw exceptions to external callers if you don't know how to handle the situation - ie in exceptional circumstances.



      In this case you already have a defined process of what to do if this happens - just use it directly without the indirect throw/catch:



      static async handleRequest(req) {
      try {
      let isAllowed = await checkIfIsAllowed(req);
      if (!isAllowed) {
      sendErrorCode("You're not allowed to do that.");
      return;
      }
      let result = await doSomething(req); // can also raise exceptions
      sendResult(result);
      } catch(err) {
      sendErrorCode(err);
      }
      }



      I could copypaste the code from the catch block into the ifcheck, but I believe this would make my code less readable and harder to maintain.




      On the contrary, as above, I would expect this to be the way to handle this situation.






      share|improve this answer















      You're checking for something and throwing an exception if isAllowed fails, but you know what to do in that situation - call sendErrorCode. You should throw exceptions to external callers if you don't know how to handle the situation - ie in exceptional circumstances.



      In this case you already have a defined process of what to do if this happens - just use it directly without the indirect throw/catch:



      static async handleRequest(req) {
      try {
      let isAllowed = await checkIfIsAllowed(req);
      if (!isAllowed) {
      sendErrorCode("You're not allowed to do that.");
      return;
      }
      let result = await doSomething(req); // can also raise exceptions
      sendResult(result);
      } catch(err) {
      sendErrorCode(err);
      }
      }



      I could copypaste the code from the catch block into the ifcheck, but I believe this would make my code less readable and harder to maintain.




      On the contrary, as above, I would expect this to be the way to handle this situation.







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Oct 30 '17 at 13:16

























      answered Oct 30 '17 at 13:07









      James ThorpeJames Thorpe

      24.3k34059




      24.3k34059








      • 1





        "You should throw exceptions to external callers if you don't know how to handle the situation - ie in exceptional circumstances." If that's true, that explains the issue. However, that means we're using exceptions wrong in the entire project, not just this function. Since there are no other answers, I'll accept this one.

        – cib
        Nov 2 '17 at 9:09














      • 1





        "You should throw exceptions to external callers if you don't know how to handle the situation - ie in exceptional circumstances." If that's true, that explains the issue. However, that means we're using exceptions wrong in the entire project, not just this function. Since there are no other answers, I'll accept this one.

        – cib
        Nov 2 '17 at 9:09








      1




      1





      "You should throw exceptions to external callers if you don't know how to handle the situation - ie in exceptional circumstances." If that's true, that explains the issue. However, that means we're using exceptions wrong in the entire project, not just this function. Since there are no other answers, I'll accept this one.

      – cib
      Nov 2 '17 at 9:09





      "You should throw exceptions to external callers if you don't know how to handle the situation - ie in exceptional circumstances." If that's true, that explains the issue. However, that means we're using exceptions wrong in the entire project, not just this function. Since there are no other answers, I'll accept this one.

      – cib
      Nov 2 '17 at 9:09













      0














      Answer of James Thorpe has one disadvantage on my opinion. It's not DRY, in both cases when you call sendError you handle Exceptions. Let's imagine we have many lines of code with logic like this where Exception can be thrown. I think it can be better.



      This is my solution



      async function doSomethingOnAllowedRequest(req) {
      let isAllowed = await checkIfIsAllowed(req);
      if (!isAllowed) {
      throw new ForbiddenException("You're not allowed to do that.");
      }
      doSomething(req);
      }
      static async handleRequest(req) {
      try {
      let result = await doSomethingOnAllowedRequest(req);
      sendResult(result);
      } catch(err) {
      sendErrorCode(err);
      }
      }





      share|improve this answer
























      • It is DRY, in that if you're not allowed to do the action, you're sending a very specific error message. The catch is there for all other exceptions. IMO you're just moving the "don't use exceptions for flow logic control" into another method here. Throwing an exception is not cheap (computationally) compared to not throwing either - if you can avoid doing so, far better to not do it.

        – James Thorpe
        Jan 17 at 16:49











      • I prefer readability to performance. IMO It's not just moving. doSomething also can throw Exception, but I don't think we can say we use exception for flow control in this case. You can doSomething only on allowed request if it not allowed you should throw the exception.

        – matchish
        Jan 17 at 17:52
















      0














      Answer of James Thorpe has one disadvantage on my opinion. It's not DRY, in both cases when you call sendError you handle Exceptions. Let's imagine we have many lines of code with logic like this where Exception can be thrown. I think it can be better.



      This is my solution



      async function doSomethingOnAllowedRequest(req) {
      let isAllowed = await checkIfIsAllowed(req);
      if (!isAllowed) {
      throw new ForbiddenException("You're not allowed to do that.");
      }
      doSomething(req);
      }
      static async handleRequest(req) {
      try {
      let result = await doSomethingOnAllowedRequest(req);
      sendResult(result);
      } catch(err) {
      sendErrorCode(err);
      }
      }





      share|improve this answer
























      • It is DRY, in that if you're not allowed to do the action, you're sending a very specific error message. The catch is there for all other exceptions. IMO you're just moving the "don't use exceptions for flow logic control" into another method here. Throwing an exception is not cheap (computationally) compared to not throwing either - if you can avoid doing so, far better to not do it.

        – James Thorpe
        Jan 17 at 16:49











      • I prefer readability to performance. IMO It's not just moving. doSomething also can throw Exception, but I don't think we can say we use exception for flow control in this case. You can doSomething only on allowed request if it not allowed you should throw the exception.

        – matchish
        Jan 17 at 17:52














      0












      0








      0







      Answer of James Thorpe has one disadvantage on my opinion. It's not DRY, in both cases when you call sendError you handle Exceptions. Let's imagine we have many lines of code with logic like this where Exception can be thrown. I think it can be better.



      This is my solution



      async function doSomethingOnAllowedRequest(req) {
      let isAllowed = await checkIfIsAllowed(req);
      if (!isAllowed) {
      throw new ForbiddenException("You're not allowed to do that.");
      }
      doSomething(req);
      }
      static async handleRequest(req) {
      try {
      let result = await doSomethingOnAllowedRequest(req);
      sendResult(result);
      } catch(err) {
      sendErrorCode(err);
      }
      }





      share|improve this answer













      Answer of James Thorpe has one disadvantage on my opinion. It's not DRY, in both cases when you call sendError you handle Exceptions. Let's imagine we have many lines of code with logic like this where Exception can be thrown. I think it can be better.



      This is my solution



      async function doSomethingOnAllowedRequest(req) {
      let isAllowed = await checkIfIsAllowed(req);
      if (!isAllowed) {
      throw new ForbiddenException("You're not allowed to do that.");
      }
      doSomething(req);
      }
      static async handleRequest(req) {
      try {
      let result = await doSomethingOnAllowedRequest(req);
      sendResult(result);
      } catch(err) {
      sendErrorCode(err);
      }
      }






      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered Jan 17 at 16:41









      matchishmatchish

      451314




      451314













      • It is DRY, in that if you're not allowed to do the action, you're sending a very specific error message. The catch is there for all other exceptions. IMO you're just moving the "don't use exceptions for flow logic control" into another method here. Throwing an exception is not cheap (computationally) compared to not throwing either - if you can avoid doing so, far better to not do it.

        – James Thorpe
        Jan 17 at 16:49











      • I prefer readability to performance. IMO It's not just moving. doSomething also can throw Exception, but I don't think we can say we use exception for flow control in this case. You can doSomething only on allowed request if it not allowed you should throw the exception.

        – matchish
        Jan 17 at 17:52



















      • It is DRY, in that if you're not allowed to do the action, you're sending a very specific error message. The catch is there for all other exceptions. IMO you're just moving the "don't use exceptions for flow logic control" into another method here. Throwing an exception is not cheap (computationally) compared to not throwing either - if you can avoid doing so, far better to not do it.

        – James Thorpe
        Jan 17 at 16:49











      • I prefer readability to performance. IMO It's not just moving. doSomething also can throw Exception, but I don't think we can say we use exception for flow control in this case. You can doSomething only on allowed request if it not allowed you should throw the exception.

        – matchish
        Jan 17 at 17:52

















      It is DRY, in that if you're not allowed to do the action, you're sending a very specific error message. The catch is there for all other exceptions. IMO you're just moving the "don't use exceptions for flow logic control" into another method here. Throwing an exception is not cheap (computationally) compared to not throwing either - if you can avoid doing so, far better to not do it.

      – James Thorpe
      Jan 17 at 16:49





      It is DRY, in that if you're not allowed to do the action, you're sending a very specific error message. The catch is there for all other exceptions. IMO you're just moving the "don't use exceptions for flow logic control" into another method here. Throwing an exception is not cheap (computationally) compared to not throwing either - if you can avoid doing so, far better to not do it.

      – James Thorpe
      Jan 17 at 16:49













      I prefer readability to performance. IMO It's not just moving. doSomething also can throw Exception, but I don't think we can say we use exception for flow control in this case. You can doSomething only on allowed request if it not allowed you should throw the exception.

      – matchish
      Jan 17 at 17:52





      I prefer readability to performance. IMO It's not just moving. doSomething also can throw Exception, but I don't think we can say we use exception for flow control in this case. You can doSomething only on allowed request if it not allowed you should throw the exception.

      – matchish
      Jan 17 at 17:52











      0














      There are good answers to the question "Why not use exceptions as normal flow control?" here.



      The reason not to throw an exception that you will catch locally is that you locally know how to handle that situation, so it is, by definition, not exceptional.



      @James Thorpe's answer looks good to me, but @matchish feels it violates DRY. I say that in general, it does not. DRY, which stands for Don't Repeat Yourself, is defined by the people who coined the phrase as "Every piece of knowledge must have a single, unambiguous, authoritative representation within a system". As applied to writing software code, it is about not repeating complex code.



      Practically any code that is said to violate DRY is said to be "fixed" by extracting the repeated code into a function and then calling that function from the places it was previously repeated. Having multiple parts of your code call sendErrorCode is the solution to fixing a DRY problem. All of the knowledge of what to do with the error is in one definitive place, namely the sendErrorCode function.



      I would modify @James Thorpe's answer slightly, but it is more of a quibble than a real criticism, which is that sendErrorCode should be receiving exception objects or strings but not both:



      static async handleRequest(req) {
      try {
      let isAllowed = await checkIfIsAllowed(req);
      if (!isAllowed) {
      sendErrorCode(new ForbiddenException("You're not allowed to do that."));
      return;
      }
      let result = await doSomething(req); // can also raise exceptions
      sendResult(result);
      } catch(err) {
      sendErrorCode(err);
      }
      }


      The larger question is what is the likelihood of the error and is it appropriate to treat !isAllowed as an exception. Exceptions are meant to handle unusual or unpredictable situations. I would expect !isAllowed to be a normal occurrence that should be handled with logic specific to that situation, unlike, say, a sudden inability to query the database that has the answer to the isAllowed question.



      @matchish's proposed solution changes the contract of doSomethingOnAllowedRequest from something that will never throw an exception to something that will routinely throw an exception, placing the burden of exception handling on all of its callers. This is likely to cause a violation of DRY by causing multiple callers to have repetitions of the same error handling code, so in the abstract I do not like it. In practice, it would depend on the overall situation, such as how many callers are there and do they, in fact, share the same response to errors.






      share|improve this answer
























      • What if you need to log errors? You should modify two lines of code, that's why I think it's not DRY.

        – matchish
        Jan 21 at 8:11











      • You write !isAllowed is not unpredictable situation, but I see ForbiddenException in your code. handleRequest created for to do something useful, and when we can't do it I think it's normal to throw the exception. For me sendErrorCode looks like throwing an exception to frontend

        – matchish
        Jan 21 at 8:20













      • @matchish "What if you need to log errors?" The !isAllowed isn't neccessarily an error/exception as far as this code is concerned (it's a handled use case), so no need to log it. At this point though, we're debating code for which we don't know the underlying semantics and use case of such things, and it's far removed from the original purpose of this Q&A.

        – James Thorpe
        Jan 21 at 9:07











      • I'm talking not about logging, it can be anything else. You have two pieces of code that will need to be changed if you need not only sendErrorCode. IMO It's not DRY

        – matchish
        Jan 21 at 9:38






      • 1





        @matchish how is logging errors in what is uniquely error handling code (sendErrorCode) more of a violation of SRP than logging errors in code whose job is to handle requests?

        – Old Pro
        Jan 23 at 7:14
















      0














      There are good answers to the question "Why not use exceptions as normal flow control?" here.



      The reason not to throw an exception that you will catch locally is that you locally know how to handle that situation, so it is, by definition, not exceptional.



      @James Thorpe's answer looks good to me, but @matchish feels it violates DRY. I say that in general, it does not. DRY, which stands for Don't Repeat Yourself, is defined by the people who coined the phrase as "Every piece of knowledge must have a single, unambiguous, authoritative representation within a system". As applied to writing software code, it is about not repeating complex code.



      Practically any code that is said to violate DRY is said to be "fixed" by extracting the repeated code into a function and then calling that function from the places it was previously repeated. Having multiple parts of your code call sendErrorCode is the solution to fixing a DRY problem. All of the knowledge of what to do with the error is in one definitive place, namely the sendErrorCode function.



      I would modify @James Thorpe's answer slightly, but it is more of a quibble than a real criticism, which is that sendErrorCode should be receiving exception objects or strings but not both:



      static async handleRequest(req) {
      try {
      let isAllowed = await checkIfIsAllowed(req);
      if (!isAllowed) {
      sendErrorCode(new ForbiddenException("You're not allowed to do that."));
      return;
      }
      let result = await doSomething(req); // can also raise exceptions
      sendResult(result);
      } catch(err) {
      sendErrorCode(err);
      }
      }


      The larger question is what is the likelihood of the error and is it appropriate to treat !isAllowed as an exception. Exceptions are meant to handle unusual or unpredictable situations. I would expect !isAllowed to be a normal occurrence that should be handled with logic specific to that situation, unlike, say, a sudden inability to query the database that has the answer to the isAllowed question.



      @matchish's proposed solution changes the contract of doSomethingOnAllowedRequest from something that will never throw an exception to something that will routinely throw an exception, placing the burden of exception handling on all of its callers. This is likely to cause a violation of DRY by causing multiple callers to have repetitions of the same error handling code, so in the abstract I do not like it. In practice, it would depend on the overall situation, such as how many callers are there and do they, in fact, share the same response to errors.






      share|improve this answer
























      • What if you need to log errors? You should modify two lines of code, that's why I think it's not DRY.

        – matchish
        Jan 21 at 8:11











      • You write !isAllowed is not unpredictable situation, but I see ForbiddenException in your code. handleRequest created for to do something useful, and when we can't do it I think it's normal to throw the exception. For me sendErrorCode looks like throwing an exception to frontend

        – matchish
        Jan 21 at 8:20













      • @matchish "What if you need to log errors?" The !isAllowed isn't neccessarily an error/exception as far as this code is concerned (it's a handled use case), so no need to log it. At this point though, we're debating code for which we don't know the underlying semantics and use case of such things, and it's far removed from the original purpose of this Q&A.

        – James Thorpe
        Jan 21 at 9:07











      • I'm talking not about logging, it can be anything else. You have two pieces of code that will need to be changed if you need not only sendErrorCode. IMO It's not DRY

        – matchish
        Jan 21 at 9:38






      • 1





        @matchish how is logging errors in what is uniquely error handling code (sendErrorCode) more of a violation of SRP than logging errors in code whose job is to handle requests?

        – Old Pro
        Jan 23 at 7:14














      0












      0








      0







      There are good answers to the question "Why not use exceptions as normal flow control?" here.



      The reason not to throw an exception that you will catch locally is that you locally know how to handle that situation, so it is, by definition, not exceptional.



      @James Thorpe's answer looks good to me, but @matchish feels it violates DRY. I say that in general, it does not. DRY, which stands for Don't Repeat Yourself, is defined by the people who coined the phrase as "Every piece of knowledge must have a single, unambiguous, authoritative representation within a system". As applied to writing software code, it is about not repeating complex code.



      Practically any code that is said to violate DRY is said to be "fixed" by extracting the repeated code into a function and then calling that function from the places it was previously repeated. Having multiple parts of your code call sendErrorCode is the solution to fixing a DRY problem. All of the knowledge of what to do with the error is in one definitive place, namely the sendErrorCode function.



      I would modify @James Thorpe's answer slightly, but it is more of a quibble than a real criticism, which is that sendErrorCode should be receiving exception objects or strings but not both:



      static async handleRequest(req) {
      try {
      let isAllowed = await checkIfIsAllowed(req);
      if (!isAllowed) {
      sendErrorCode(new ForbiddenException("You're not allowed to do that."));
      return;
      }
      let result = await doSomething(req); // can also raise exceptions
      sendResult(result);
      } catch(err) {
      sendErrorCode(err);
      }
      }


      The larger question is what is the likelihood of the error and is it appropriate to treat !isAllowed as an exception. Exceptions are meant to handle unusual or unpredictable situations. I would expect !isAllowed to be a normal occurrence that should be handled with logic specific to that situation, unlike, say, a sudden inability to query the database that has the answer to the isAllowed question.



      @matchish's proposed solution changes the contract of doSomethingOnAllowedRequest from something that will never throw an exception to something that will routinely throw an exception, placing the burden of exception handling on all of its callers. This is likely to cause a violation of DRY by causing multiple callers to have repetitions of the same error handling code, so in the abstract I do not like it. In practice, it would depend on the overall situation, such as how many callers are there and do they, in fact, share the same response to errors.






      share|improve this answer













      There are good answers to the question "Why not use exceptions as normal flow control?" here.



      The reason not to throw an exception that you will catch locally is that you locally know how to handle that situation, so it is, by definition, not exceptional.



      @James Thorpe's answer looks good to me, but @matchish feels it violates DRY. I say that in general, it does not. DRY, which stands for Don't Repeat Yourself, is defined by the people who coined the phrase as "Every piece of knowledge must have a single, unambiguous, authoritative representation within a system". As applied to writing software code, it is about not repeating complex code.



      Practically any code that is said to violate DRY is said to be "fixed" by extracting the repeated code into a function and then calling that function from the places it was previously repeated. Having multiple parts of your code call sendErrorCode is the solution to fixing a DRY problem. All of the knowledge of what to do with the error is in one definitive place, namely the sendErrorCode function.



      I would modify @James Thorpe's answer slightly, but it is more of a quibble than a real criticism, which is that sendErrorCode should be receiving exception objects or strings but not both:



      static async handleRequest(req) {
      try {
      let isAllowed = await checkIfIsAllowed(req);
      if (!isAllowed) {
      sendErrorCode(new ForbiddenException("You're not allowed to do that."));
      return;
      }
      let result = await doSomething(req); // can also raise exceptions
      sendResult(result);
      } catch(err) {
      sendErrorCode(err);
      }
      }


      The larger question is what is the likelihood of the error and is it appropriate to treat !isAllowed as an exception. Exceptions are meant to handle unusual or unpredictable situations. I would expect !isAllowed to be a normal occurrence that should be handled with logic specific to that situation, unlike, say, a sudden inability to query the database that has the answer to the isAllowed question.



      @matchish's proposed solution changes the contract of doSomethingOnAllowedRequest from something that will never throw an exception to something that will routinely throw an exception, placing the burden of exception handling on all of its callers. This is likely to cause a violation of DRY by causing multiple callers to have repetitions of the same error handling code, so in the abstract I do not like it. In practice, it would depend on the overall situation, such as how many callers are there and do they, in fact, share the same response to errors.







      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered Jan 19 at 23:56









      Old ProOld Pro

      14.7k23767




      14.7k23767













      • What if you need to log errors? You should modify two lines of code, that's why I think it's not DRY.

        – matchish
        Jan 21 at 8:11











      • You write !isAllowed is not unpredictable situation, but I see ForbiddenException in your code. handleRequest created for to do something useful, and when we can't do it I think it's normal to throw the exception. For me sendErrorCode looks like throwing an exception to frontend

        – matchish
        Jan 21 at 8:20













      • @matchish "What if you need to log errors?" The !isAllowed isn't neccessarily an error/exception as far as this code is concerned (it's a handled use case), so no need to log it. At this point though, we're debating code for which we don't know the underlying semantics and use case of such things, and it's far removed from the original purpose of this Q&A.

        – James Thorpe
        Jan 21 at 9:07











      • I'm talking not about logging, it can be anything else. You have two pieces of code that will need to be changed if you need not only sendErrorCode. IMO It's not DRY

        – matchish
        Jan 21 at 9:38






      • 1





        @matchish how is logging errors in what is uniquely error handling code (sendErrorCode) more of a violation of SRP than logging errors in code whose job is to handle requests?

        – Old Pro
        Jan 23 at 7:14



















      • What if you need to log errors? You should modify two lines of code, that's why I think it's not DRY.

        – matchish
        Jan 21 at 8:11











      • You write !isAllowed is not unpredictable situation, but I see ForbiddenException in your code. handleRequest created for to do something useful, and when we can't do it I think it's normal to throw the exception. For me sendErrorCode looks like throwing an exception to frontend

        – matchish
        Jan 21 at 8:20













      • @matchish "What if you need to log errors?" The !isAllowed isn't neccessarily an error/exception as far as this code is concerned (it's a handled use case), so no need to log it. At this point though, we're debating code for which we don't know the underlying semantics and use case of such things, and it's far removed from the original purpose of this Q&A.

        – James Thorpe
        Jan 21 at 9:07











      • I'm talking not about logging, it can be anything else. You have two pieces of code that will need to be changed if you need not only sendErrorCode. IMO It's not DRY

        – matchish
        Jan 21 at 9:38






      • 1





        @matchish how is logging errors in what is uniquely error handling code (sendErrorCode) more of a violation of SRP than logging errors in code whose job is to handle requests?

        – Old Pro
        Jan 23 at 7:14

















      What if you need to log errors? You should modify two lines of code, that's why I think it's not DRY.

      – matchish
      Jan 21 at 8:11





      What if you need to log errors? You should modify two lines of code, that's why I think it's not DRY.

      – matchish
      Jan 21 at 8:11













      You write !isAllowed is not unpredictable situation, but I see ForbiddenException in your code. handleRequest created for to do something useful, and when we can't do it I think it's normal to throw the exception. For me sendErrorCode looks like throwing an exception to frontend

      – matchish
      Jan 21 at 8:20







      You write !isAllowed is not unpredictable situation, but I see ForbiddenException in your code. handleRequest created for to do something useful, and when we can't do it I think it's normal to throw the exception. For me sendErrorCode looks like throwing an exception to frontend

      – matchish
      Jan 21 at 8:20















      @matchish "What if you need to log errors?" The !isAllowed isn't neccessarily an error/exception as far as this code is concerned (it's a handled use case), so no need to log it. At this point though, we're debating code for which we don't know the underlying semantics and use case of such things, and it's far removed from the original purpose of this Q&A.

      – James Thorpe
      Jan 21 at 9:07





      @matchish "What if you need to log errors?" The !isAllowed isn't neccessarily an error/exception as far as this code is concerned (it's a handled use case), so no need to log it. At this point though, we're debating code for which we don't know the underlying semantics and use case of such things, and it's far removed from the original purpose of this Q&A.

      – James Thorpe
      Jan 21 at 9:07













      I'm talking not about logging, it can be anything else. You have two pieces of code that will need to be changed if you need not only sendErrorCode. IMO It's not DRY

      – matchish
      Jan 21 at 9:38





      I'm talking not about logging, it can be anything else. You have two pieces of code that will need to be changed if you need not only sendErrorCode. IMO It's not DRY

      – matchish
      Jan 21 at 9:38




      1




      1





      @matchish how is logging errors in what is uniquely error handling code (sendErrorCode) more of a violation of SRP than logging errors in code whose job is to handle requests?

      – Old Pro
      Jan 23 at 7:14





      @matchish how is logging errors in what is uniquely error handling code (sendErrorCode) more of a violation of SRP than logging errors in code whose job is to handle requests?

      – Old Pro
      Jan 23 at 7:14











      0





      +50









      Since this is not a blocking error, but only an IDE recommendation, then the question should be viewed from two sides.



      The first side is performance. If this is a bottleneck and it is potentially possible to use it with compilation or when transferring to new (not yet released) versions of nodejs, the presence of repetitions is not always a bad solution. It seems that the IDE hints precisely in this case and that such a design can lead to poor optimization in some cases.



      The second side is the code design. If it will make the code more readable and simplify the work for other developers - keep it. From this point of view, solutions have already been proposed above.






      share|improve this answer






























        0





        +50









        Since this is not a blocking error, but only an IDE recommendation, then the question should be viewed from two sides.



        The first side is performance. If this is a bottleneck and it is potentially possible to use it with compilation or when transferring to new (not yet released) versions of nodejs, the presence of repetitions is not always a bad solution. It seems that the IDE hints precisely in this case and that such a design can lead to poor optimization in some cases.



        The second side is the code design. If it will make the code more readable and simplify the work for other developers - keep it. From this point of view, solutions have already been proposed above.






        share|improve this answer




























          0





          +50







          0





          +50



          0




          +50





          Since this is not a blocking error, but only an IDE recommendation, then the question should be viewed from two sides.



          The first side is performance. If this is a bottleneck and it is potentially possible to use it with compilation or when transferring to new (not yet released) versions of nodejs, the presence of repetitions is not always a bad solution. It seems that the IDE hints precisely in this case and that such a design can lead to poor optimization in some cases.



          The second side is the code design. If it will make the code more readable and simplify the work for other developers - keep it. From this point of view, solutions have already been proposed above.






          share|improve this answer















          Since this is not a blocking error, but only an IDE recommendation, then the question should be viewed from two sides.



          The first side is performance. If this is a bottleneck and it is potentially possible to use it with compilation or when transferring to new (not yet released) versions of nodejs, the presence of repetitions is not always a bad solution. It seems that the IDE hints precisely in this case and that such a design can lead to poor optimization in some cases.



          The second side is the code design. If it will make the code more readable and simplify the work for other developers - keep it. From this point of view, solutions have already been proposed above.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Jan 21 at 11:33

























          answered Jan 21 at 11:24









          SlowSupermanSlowSuperman

          1541211




          1541211























              -3














              This could give you some tips, maybe that can be the cause(not sure if relevant).
              Catch statement does not catch thrown error



              "
              The reason why your try catch block is failing is because an ajax request is asynchronous. The try catch block will execute before the Ajax call and send the request itself, but the error is thrown when the result is returned, AT A LATER POINT IN TIME.



              When the try catch block is executed, there is no error. When the error is thrown, there is no try catch. If you need try catch for ajax requests, always put ajax try catch blocks inside the success callback, NEVER outside of it."






              share|improve this answer




























                -3














                This could give you some tips, maybe that can be the cause(not sure if relevant).
                Catch statement does not catch thrown error



                "
                The reason why your try catch block is failing is because an ajax request is asynchronous. The try catch block will execute before the Ajax call and send the request itself, but the error is thrown when the result is returned, AT A LATER POINT IN TIME.



                When the try catch block is executed, there is no error. When the error is thrown, there is no try catch. If you need try catch for ajax requests, always put ajax try catch blocks inside the success callback, NEVER outside of it."






                share|improve this answer


























                  -3












                  -3








                  -3







                  This could give you some tips, maybe that can be the cause(not sure if relevant).
                  Catch statement does not catch thrown error



                  "
                  The reason why your try catch block is failing is because an ajax request is asynchronous. The try catch block will execute before the Ajax call and send the request itself, but the error is thrown when the result is returned, AT A LATER POINT IN TIME.



                  When the try catch block is executed, there is no error. When the error is thrown, there is no try catch. If you need try catch for ajax requests, always put ajax try catch blocks inside the success callback, NEVER outside of it."






                  share|improve this answer













                  This could give you some tips, maybe that can be the cause(not sure if relevant).
                  Catch statement does not catch thrown error



                  "
                  The reason why your try catch block is failing is because an ajax request is asynchronous. The try catch block will execute before the Ajax call and send the request itself, but the error is thrown when the result is returned, AT A LATER POINT IN TIME.



                  When the try catch block is executed, there is no error. When the error is thrown, there is no try catch. If you need try catch for ajax requests, always put ajax try catch blocks inside the success callback, NEVER outside of it."







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Oct 30 '17 at 13:15









                  Di VDi V

                  60110




                  60110






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f47015693%2fhow-to-fix-throw-of-exception-caught-locally%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Liquibase includeAll doesn't find base path

                      How to use setInterval in EJS file?

                      Petrus Granier-Deferre