The promise falls through without a safety net

Attempting to grasp the concept of error handling in promises has left me confused. Despite researching extensively, I am unable to figure out why it's not working as expected. To simulate a potential error situation, I have created a sample method where I deliberately throw an error:

DeleteProject(id: string, customerId: string): Promise<void> {
    throw new Error('test error');
}

Subsequently, I invoke this method in my code like so:

projectService.DeleteProject(state.FocusedProject.ID, state.FocusedProject.CustomerID)
    .then(() => {
        ...actions upon success...
    })
    .catch(error => {
        console.log('caught you');
        HandleError(error, 'Delete Project');
    });

When the method does not throw an error, everything functions correctly, and the code within the then block is executed without issues. However, when an error is thrown, an unhandled exception occurs, and the catch block remains untouched.

My understanding from various resources is that throwing an error inside a function should automatically trigger its catch block and return a rejected promise. So, why isn't it being caught in this scenario?

I suspect I am overlooking something critical, but I cannot pinpoint what it might be. Essentially, I want the catch block to handle any errors that occur within the invoked method.

Answer ā„–1

It has been noted in the comments that DeleteProject is specified to return a Promise<void>, yet it lacks the async keyword. Functions without async can throw errors which are handled within a try/catch block instead of using Promise.then or Promise.catch. These distinct error channels must be managed separately.

The Promise mechanism will automatically convert errors thrown with throw into rejected Promises under specific circumstances:

  1. During instantiation of a new Promise object.
  2. When passed to Promise.then or Promise.catch.
  3. In an async function.

If there is no specific need for handling errors synchronously, it may be advisable to use

return Promise.reject(new Error(...))
over throw new Error(...) in DeleteProject. This approach provides consistency for callers by utilizing a single error channel regardless of whether the error is synchronous or asynchronous due to server communication.

A subsequent comment from sfaust suggests the necessity of managing both types of errors ā€“ those originating asynchronously from the server and synchronously from invalid input. Addressing the distinction between development-time and runtime errors is logical, but clear documentation regarding DeleteProject's potential to generate both error types is crucial. Even when errors can be caught instantly, the decision of what external API to offer to function callers remains your responsibility. For manually-crafted functions returning promises (without async), employing a consistent approach, such as always transmitting errors through rejected promises, ensures predictability. This may involve enclosing the function in a try/catch block and utilizing a specialized subclass of Error to indicate improper function calls.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The inefficiency of invoking Jquery on elements that do not exist for the purpose of caching

What is the impact if JQuery attempts to access elements that do not exist? Will there be any significant CPU overhead other than script loading? Does it matter if this is done for a class or an id? For optimization purposes and to minimize simultaneous c ...

Using a for loop to create visualizations using amCharts in JavaScript

Is there a more efficient way to generate multiple line charts simultaneously? I've tried using the code below, but it's not working as expected. Any suggestions on how to generate graphs using looping mechanisms like for/while loops? I have a la ...

When using Three.js raycaster to intersect objects, it may not function properly if THREE.Points contains only one vertex or if the vertices are arranged in a straight line

I've spent quite a bit of time trying to figure out this issue. It seems that the raycaster.intersectObject( pointCloud ); method does not intersect my 'pointCloud' Object when it only has one vertex in its position array attribute with thre ...

Hide an absolutely positioned div when another element is clicked outside of it

Here is the code for the function that executes when a button on my website is clicked: function displayOverlay() { document.getElementById("overlay").style.visibility = "visible"; document.getElementById("dim").style.visibility = "visible"; d ...

Use JavaScript to retrieve a value and display it on a PHP page

I am trying to create a system that can generate and deliver JSON data. Here is the PHP code I have so far: <?php header("Content-Type:application/json"); require "data.php"; if(!empty($_GET['name'])) { $name=$_GET['name']; ...

ES6 arrow function fails to recognize the 'this' operator after being transpiled into JavaScript

Currently, I am developing a node application that undergoes transpilation from TypeScript ES6 to JavaScript ES6. To manage class dependencies, I am employing inversify for dependency injection. However, I encountered an error while trying to access member ...

What is the best way to eliminate any extra spaces from a string using typescript?

Currently in my Angular 5 project, I am encountering an issue with using the .trim() function in TypeScript on a string. Despite implementing it as shown below, no whitespace is being removed and also there are no error messages appearing: this.maintabinf ...

Making changes to an input field can impact other elements when using the v-model directive

I am facing an issue with a cart setup where the quantity of all products are being updated when I increase the quantity of one product. How can I prevent this and only update the quantity of the selected product? <div v-for="(product, index) in cartPr ...

Adding distinct objects in React.js

Currently experimenting with building an e-commerce application using React just for fun. Iā€™m facing a challenge in setting state on a specific object as it gets added to an array. My scenario involves an array called cart where items selected from the ...

What could be causing this compatibility issue between IE and Chrome? It's strange that the Table is displaying correctly only in Chrome

Recently, I encountered a challenge with my code in Chrome and realized that it also needs to work in Internet Explorer. Can someone assist me in making it fully functional in IE? I suspect that there might be specific code adjustments needed for IE as th ...

Determine the prior location of an element using jQuery

Is there a way to track the previous location of an element before it is appended? I have 50 elements that need to be appended to different targets based on a certain condition. How can I determine where each element was located before being moved? $(&a ...

Problems arise when using $(window).width() in conjunction with scrolling functionality

I am attempting to ensure this code only activates when the device window exceeds 960px and triggers when the window scrolls down 700px. The second condition is functioning as intended, but the first condition is not working properly. The code functions f ...

What could be causing my fetch post request to only hit on breakpoint and not otherwise?

In my React .Net application, I am using the following code snippet: handleAdd(userId, name) { name = encodeURIComponent(name); fetch('api/deck/create/' + userId + '/' + name, { method: 'POST' }).then(); } This ...

VueRouter child route with trailing slash after default

VueRouter automatically includes a trailing slash before the child route's path. Consider this example of a route configuration: const routes = [ path: '/home', components: { default: HomeBase }, children: [ ...

What's the best way to incorporate local storage into my Calculator application?

I'm currently working on a calculator project and I have all the necessary resources at hand. The only thing left to do is to incorporate LocalStorage beneath the Result section. This way, the Calculator will keep track of each result until the sessio ...

Auto-populate model objects with information automatically

I have a model... export class myModel{ PropertyA: string; PropertyB: number; PropertyC: string; PropertyD: number; } The data retrieved consists of... this.store.select(myDataStoreName) .subscribe(data=> { } This is how the ret ...

The functionality of the .toggle method is limited to only being effective 1.5

I'm having an issue with making an image popup using the .toggle function in javascript. It seems to work initially, but then only works partially after that. When I click on the image, it opens as expected. However, when I try to close it by clickin ...

Exploring how to alter state in a child component using a function within the parent component in React

class ParentComponent extends Component { state = { isDialogOpen: false, setStyle: false } handleClose = () => { this.setState({ isDialogOpen: false, setStyle: false }) } handleOpen = () => { this.setState({ isDialogOpen: true ...

In JavaScript, you can verify whether the content or blank space of an element was clicked

Is it possible to determine if the clicked part of an element is text or white space? https://i.sstatic.net/0pFgB.jpg My attempts so far have been unsuccessful: body.addEventListener('contextmenu', (e) => { e.preventDefault(); // Prevent ...