Effective error management when dispatching a POST request using redux

Hello, I am a newcomer to Redux and I am currently looking for guidance on how to effectively manage errors when dispatching a POST request using axios with thunk. Specifically, I am trying to properly handle any errors that may arise from the extra reducers in my code. Currently, I am utilizing console.log to temporarily log any errors encountered. Any advice or feedback on my approach would be greatly appreciated! Below is a snippet of the relevant code:

export const postInfo = createAsyncThunk(
  'info/postInfo',
  async (infoObject: InfoRequest) => {
    const response = await axios.post(`${url}/info`, infoObject);
    return response.data;
  }
);
...
extraReducers: (builder) => {
  builder
    ....
    .addCase(postInfo.rejected, (state, action) => {
      state.request.status = 'failed';
      state.request.error = action.error.message;
    })
}
...
const sendInfoRequest = async () => {
  try {
    const infoObjRequest: InfoRequest = {
      userId: 8,
      firstName: 'John',
      lastName: 'Smith'
    };
    await dispatch(postInfo(infoObjRequest));
  } catch (err) {
       // TODO: how to use error handling for rejected?      
       console.log('rejected for post /info', err);
  }
};

Answer №1

You have the option to utilize unwrapping-result-actions for this purpose.

For instance:

index.ts:

import { configureStore, createAsyncThunk, createSlice, unwrapResult } from '@reduxjs/toolkit';

export const postInfo = createAsyncThunk('info/postInfo', async () => {
  throw new Error('get post info fails');
});
const postInfoSlice = createSlice({
  name: 'postInfo',
  initialState: {
    request: { status: 'idle', error: '' },
  },
  reducers: {},
  extraReducers: (builder) => {
    builder.addCase(postInfo.rejected, (state, action) => {
      state.request.status = 'failed';
      state.request.error = action.error.message as string;
    });
  },
});

const store = configureStore({ reducer: postInfoSlice.reducer });

const sendInfoRequest = async () => {
  try {
    await store.dispatch(postInfo()).unwrap();
  } catch (err) {
    console.log('rejected for post /info', err);
  }
};

sendInfoRequest();

Outcome of execution:

rejected for post /info {
  name: 'Error',
  message: 'get post info fails',
  stack: 'Error: get post info fails\n' +
    '    at /Users/dulin/workspace/github.com/mrdulin/redux-examples/packages/redux-toolkit-example/stackoverflow/71070359/index.ts:4:9\n' +
    '    at step (/Users/dulin/workspace/github.com/mrdulin/redux-examples/packages/redux-toolkit-example/stackoverflow/71070359/index.ts:33:23)\n' +
    '    at Object.next (/Users/dulin/workspace/github.com/mrdulin/redux-examples/packages/redux-toolkit-example/stackoverflow/71070359/index.ts:14:53)\n' +
    '    at /Users/dulin/workspace/github.com/mrdulin/redux-examples/packages/redux-toolkit-example/stackoverflow/71070359/index.ts:8:71\n' +
    '    at new Promise (<anonymous>)\n' +
    '    at __awaiter (/Users/dulin/workspace/github.com/mrdulin/redux-examples/packages/redux-toolkit-example/stackoverflow/71070359/index.ts:4:12)\n' +
    '    at /Users/dulin/workspace/github.com/mrdulin/redux-examples/packages/redux-toolkit-example/stackoverflow/71070359/index.ts:3:59\n' +
    '    at /Users/dulin/workspace/github.com/mrdulin/redux-examples/packages/redux-toolkit-example/node_modules/@reduxjs/toolkit/dist/redux-toolkit.cjs.development.js:1172:57\n' +
    '    at step (/Users/dulin/workspace/github.com/mrdulin/redux-examples/packages/redux-toolkit-example/node_modules/@reduxjs/toolkit/dist/redux-toolkit.cjs.development.js:38:23)\n' +
    '    at Object.next (/Users/dulin/workspace/github.com/mrdulin/redux-examples/packages/redux-toolkit-example/node_modules/@reduxjs/toolkit/dist/redux-toolkit.cjs.development.js:19:53)'
}

Alternatively, you can return a rejected value using thunkAPI.rejectWithValue() instead of throwing an error in the thunk function.

export const postInfo = createAsyncThunk('info/postInfo', async (_, thunkAPI) => {
  // throw new Error('get post info fails');
  return thunkAPI.rejectWithValue({ code: 2000, message: 'parameter invalid' });
});

Outcome of execution:

rejected for post /info { code: 2000, message: 'parameter invalid' }

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 pairing of Transpiller and Internet Explorer 8 is like a dynamic

In starting my new project, I am considering using BabelJS. However, there is a significant requirement that must be met: it needs to be compatible with IE8. ISSUE: Babel compiles ES6 to ES5, but the support for ES5 on IE8 is lacking. Are there any alter ...

What is the best way to save a Map for future use in different components?

Let's say I define an enum like this: export enum SomeEnum { SomeLongName = 1, AnotherName = 2 } Within my display components, I'm utilizing an enum map to translate the enum values into strings for presentation on the web app: enumMap = new Map ...

Rendering Information in Angular 4 Through Rest API

Encountering issues displaying data from my local express.js REST API, organized as follows: people: [{ surname: 'testsurname', name: 'testname', email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemai ...

The reason behind the clickable issue with my duplicate <ion-select>

I've been working on a form using HTML, CSS, and JavaScript where I implemented an "Add" button to duplicate the form. The issue arises with the ion-select element within the duplicated form. While the original form displays all predefined options upo ...

Encountering issues while incorporating decimal.js in TypeScript

Incorporating decimal.js into my TypeScript project has proven to be challenging. When attempting to run the code snippet below, I encounter the following error message: Cannot assign to read only property 'constructor' of object '[object Ob ...

Utilizing Azure Function Model v4: Establishing a Connection with Express.js

Using Model v4 in my Azure function index.ts import { app } from "@azure/functions"; import azureFunctionHandler from "azure-aws-serverless-express"; import expressApp from "../../app"; app.http("httpTrigger1", { methods: ["GET"], route: "api/{*segme ...

Discover the solution to the issue of bookmarking a card on a page using react, typescript, and mui!

Whenever I try to favorite a card by clicking on its icon, all cards of the same type get bookmarked instead of just the one I clicked on. This is causing an issue where multiple cards are being favorited per page when I only want to bookmark individual on ...

I am currently attempting to implement a redirect feature after logging in using Angular. However, I encountered an error stating, "The argument of type 'string | null' cannot be assigned to a parameter of type 'string | UrlTree'."

Below is the code snippet from my auth.service.ts file: import { Injectable } from "@angular/core"; import { GoogleAuthProvider } from 'firebase/auth'; import { AngularFireAuth } from '@angular/fire/compat/auth'; import { Obse ...

Utilizing a powerful combination of Angular 5, PrimeNG charts, Spring Boot, and JHipster

I am facing an issue with creating charts using PrimeNG. The main challenge I'm encountering is the conversion of data from a REST API in Angular 5 (TypeScript) and retrieving the list of measurements from the API. I have an endpoint that returns my m ...

Having trouble retrieving form values in Typescript React, only receiving HTML tag as output

I am having an issue with retrieving the form value to my useRef hook as it returns the HTML tag of the form instead. To solve this, I attempted to specify the type HTMLFormElement inside the chevrons and set null as the initial value for my useRef hook. ...

The property xyz is not found in the type 'IntrinsicAttributes & interface abc'

I have an array of objects structured like this: const data = { "Large_Plates": [ { "name": "Cauliower/ Shanghai Fried rice with stir fry vegetables", "id": "1", "price_Veg&quo ...

The reduce function doesn't return a value in JavaScript

const items = [ { item: 'apple', cost: 2 }, { item: 'orange', cost: 4 }, { item: 'pear', cost: ' ' }, { item: 'grape', cost: 6 }, { item: 'watermelon', cost: 8 }, { item: 'kiwi', cost: & ...

Ways to access the properties of a component in React

I am working on a component that is designed to accept another component as a prop. In addition to passing down the child component, it also passes down any other props that it receives. Here is an example of what I am trying to achieve: interface FormGro ...

Traverse the elements of a BehaviorSubject named Layer_Template

I am currently facing an issue with displaying data from my BehaviorSubject. I have come across a way to iterate through a BehaviorSubject using asyncpipe which subscribes to the Observable SERVICE todo.service.ts @Injectable() export class TodoService ...

Combining string types with spaces and accepted types in TypeScript, potentially recursive

type AcceptedClass = "one" | "two" | "three"; type ClassNameType = `${AcceptedClass} ${ClassNameType}`; const className: ClassNameType = "one two three"; const className2: ClassNameType = "two one three one th ...

What is the simplest way to incorporate Vue with Typescript, without the need for a complex build setup?

I've been spending the last couple of days experimenting with my basic ASP.NET Core website set up for Typescript 2.9, but unfortunately, I haven't made much progress. My main goal is to keep the front-end simple, with just single Vue apps on eac ...

Error message "Unable to access property 'picture' of null" occurs in Angular 2 with Auth0 upon successful login

I've successfully implemented Auth0 authentication in my Angular 2 application. However, upon signing in, I encounter an error stating "Cannot read property 'picture' of null." Oddly enough, if I refresh the page, the user is shown as logged ...

The process of extracting all arrays from a JSON object

Within my JSON object, there is a list of countries each with multiple regions stored in an array. My goal is to extract and combine all the regions into one single list. However, when I attempt to map the data, it does not consolidate all the regions as e ...

Expanding superagent functionality through proxy integration

I am facing an issue where I cannot find any TypeScript definitions for the module superagent-proxy. This leads to errors when compiling my TypeScript application to JavaScript, specifically: ts: Property 'proxy' does not exist on type 'S ...

Filling out Modal Forms with angular

My issue is with using ngFor to generate and display data within a modal form. When clicking on any element, only the data of the first element on the page appears in the modal form. How can I make it so that the data changes for each element clicked? He ...