Creating a Comprehensive Error Handling System with Strong Typing in TypeScript

Seeking a more efficient approach, I aim to centralize all error handling in one global function instead of scattering try catch blocks everywhere. While appending await func().catch() can capture errors, here is the global solution proposed:

async function errorhandler(func) {
 try{
   const result = await func();
   return [result, null];
 }catch (err) {
   console.log(err);
   return [null, err];
 }
}

For implementation, consider using it as follows:

function mainFunction(){
  const url = "https://jsonplaceholder.typicode.com/todos/"
  const [data, error] = errorhandler(fetch(url));
  if(error) //take necessary action
  data. //missing method intellisense ?
}

mainFunction()

Unfortunately, this setup results in loss of autocompletion support. Attempts were made to introduce types, like so:

async function errorhandler(func: () => Promise<T>): any {
 try{
  const result = await func();
  return [result, null];
 }catch (err) {
  console.log(err);
  return [null, err];
 }
}

function mainFunction(){
  const url = "https://jsonplaceholder.typicode.com/todos/"
  const [data, error]: any = errorhandler(() => fetch(url));
  if(error) //take necessary action
  data. //no intellisense
}

mainFunction()

Despite these efforts, the issue persists. Any insights or guidance on achieving autocomplete for data methods with type safety would be greatly appreciated.

The expectation is to have access to autocomplete suggestions for all available methods under the data field, ensuring type integrity.

Answer №1

Upon reviewing your second attempt, it appears that there are several issues that need to be addressed.

  • The function lacks generic parameters, yet you are attempting to use T.

  • The return type is simply set as any.

  • While the function is marked as async, you are not utilizing await for the result.

  • In addition, you have designated the resulting tuple with any.

To rectify these problems, I recommend typing the return type of errorHandler as a discriminated union of [null, unknown] | [T, null], which can be narrowed down by checking the truthiness of data.

async function errorHandler<T>(
  func: () => Promise<T>
): Promise<[null, unknown] | [T, null]> {
  try {
    const result = await func();
    return [result, null];
  } catch (err) {
    console.log(err);
    return [null, err];
  }
}

async function mainFunction() {
  const url = "https://jsonplaceholder.typicode.com/todos/";
  const [data, error] = await errorHandler(() => fetch(url));
  if (!data) {
    data;
    // ^? const data: null

    error;
    // ^? const error: unknown
  } else {
    data;
    // ^? const data: Response

    error;
    // ^? const error: null
  }
}

Playground

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

What's new with event handling in Vue 3.0?

Looking for a way to handle an event in a child component, check for a specific condition, and then emit the "submit" event back to the parent for its event handler to run. The code snippet below demonstrates this process using Vue.js 2.6.11 (replacing "vu ...

Angular Material table does not support the use of colspan feature

Can Angular Material tables support colspan, or is there an alternative method to achieve this? I attempted using [attr.colspan], but the result was not as expected. When I added [attr.colspan], it applied the colspan but shifted symbols to a different un ...

Exploring the _embedded section within a Json Response

Having difficulty accessing the _embedded property within Json in Angular. Wondering if it's even possible. The Json response, created using Spring-Data-Jpa, is structured like this: { "_embedded": { "reviews": [ { "author": " ...

Automatic type inference for functions in TypeScript with arguments

I am looking to define an interface with the following structure: interface CheckNActSetup<D, C> { defs: (event: Event) => D, context: (defs: D) => C; exec: (context: C) => any[]; when: ((context: C) => boolean)[]; } and implement it usi ...

What steps should I take to resolve the 'invalid mime type' issue while transmitting an image as a binary string to Stability AI via Express?

Currently, I am facing an issue while attempting to utilize the image-to-image API provided by stabilityAI. The task at hand involves sending an image as a binary string through my express server to the stability AI API. However, when I make the POST reque ...

Developing a constrained variable limited to specific values

Recently delving into Typescript - I am interested in creating a variable type that is restricted to specific values. For instance, I have an element where I want to adjust the width based on a "zoom" variable. I would like to define a variable type call ...

Ensure that all other components executed prior to initiating the button's mousedown event

Within my formly setup, there is a button with a mousedown event triggering a method named "analyzeClick()" <button *ngIf="show" (mousedown)="analyzeClick()" id={{htmlID}}> {{label}} </button> Additionally, we have input ...

Tips for triggering the update of index.view when the Save command is triggered within an active dialog

When I try to save in an open dialog using the Save command, the parent index.view does not update. However, everything works fine when using the SaveAndClose command. This was tested on the Product object at https://github.com/alex-kukhtin/A2v10.Web.Sampl ...

Navigating to the detail page following a POST request in RTK query: A step-by-step guide

In my React RTK-query form, I am facing an issue where after a POST request is made, the form should navigate to the next step. However, in order to do that, I need to obtain the id of the newly created record. The backend auto-increments the id and does n ...

How to define an array of objects in data using Vue.js and TypeScript

Encountering errors when attempting to declare an array of objects in Vue.js 3 + TypeScript. The code snippet includes a template, script, and style sections. <template> <ul > <li v-if="!items.length">...loading</li> ...

NextJS and AWS Amplify collaboration for secure authentication routing

After hours of research, I'm struggling to navigate the authentication routing in NextJS combined with AWS Amplify. As a newcomer to NextJS, I want to implement a feature that disables the login/register page for users who are already logged in and pr ...

Using TypeScript to expand a class by introducing a constructor with Partial<Type>

How can the User class be extended in TypeScript using Partial<User> as the constructor? I am open to alternative solutions that do not involve Partial. For instance, initializing a blank class with new User({}) Currently, the AdvancedUser class on ...

Nest JS encountering an error due to an undefined property

Recently, my application was running smoothly until I attempted to fetch the documentation using Swagger. It seems like there might be a dependency issue causing it to stop working, but I can't pinpoint the root of the problem. An error message keeps ...

Azure pipeline failing to run Visual Studio 2017 task because of outdated Typescript SDK version

The Visual Studio 2017 build encounters an error during the build process src\Service\node_modules\utility-types\dist\aliases-and-guards.d.ts(10,51): Error TS2304: Build:Cannot find name 'bigint This issue is specific to the ...

What is the best way to implement multiple templates for a single component?

Is there a way to configure my Home Component based on the user's role? For instance: If the employee is an admin, then the home component should load the template URL designed for admins. Likewise, if the employee is a cashier, then the home compo ...

Tips for working with Typescript: utilizing the default value for a non-existent computed property

When utilizing Computed Property in javascript, I can structure my code as follows const default_values = {a:"debug",b:"info",c:"warning"}; function execute(y) { let x = default_values[y] || default_values.a /* if y is no ...

In Visual Studio, consider reporting typescript errors as warnings instead of causing the build to fail

My goal is to perform type checking on my existing JavaScript code. I have set up a tsconfig file with the specifications below. When I run tsc, it generates hundreds of errors that appear in Visual Studio during the build process. These errors are current ...

Send a collection of Angular components to an HTML template by passing them as an

Scenario :- I am working on a small Angular application with only two tabs displayed on a single screen, deployed independently as static assets in an AWS S3 bucket. Situation :- Within one of my Angular (version 12) container components, I have lengthy m ...

Combining marker, circle, and polygon layers within an Angular 5 environment

I am working on a project where I have an array of places that are being displayed in both a table and a map. Each element in the table is represented by a marker, and either a circle or polygon. When an element is selected from the table, the marker icon ...

What is the recommended substitute for the "any" type in TypeScript?

Code Slider.tsx import { useSelector, connect } from "react-redux"; import { ProductType, ProductItem, StateType } from "types"; const Slider = ({ products, number }: any) => { ------------------> what type? // const number = ...