Keep Observable open even in the event of an error

While the question may seem simple, finding reliable resources on error handling for Observables can be a challenge. I've been struggling to locate clear information online (or perhaps my search skills need improvement).

In my scenario, I have an http request that returns an Observable of type Response. These Responses may contain either data or an error message. When there is data, I want to extract and parse it. But if the Response contains an error message, I want to skip all subsequent operators related to parsing and immediately execute the error function within the subscriber.

I currently achieve this by throwing an Error:

http.get(...).
...
.do(res=>{
  if(res.error) throw new Error(res.error.message);
  return res;
})

This approach successfully skips the parsing operators and triggers the error function. However, the issue arises after encountering an error—the Subscriber stops accepting data at that point.

Upon examining the Subscriber post-error, I observed that both the properties closed and isStopped are set to true. My goal is to prevent this premature closure and maintain the Observable active even after errors occur. How can I accomplish this?

Thank you

Answer №1

In previous responses, it has been emphasized that the standard behavior of Rxjs observables is contractually guaranteed. If you wish to deviate from these contracts, you have the option to 'materialize' your source. In doing so, instead of handling messages flowing through your observable, you will work with meta-messages (referred to as notifications) including 'next', 'error', and 'complete' types. Meta-messages do not adhere to any specific contract, requiring you to manually craft error and complete messages or revert to standard behavior using 'dematerialize'.

Observables are well-suited for managing dataflow, while tasks involving control flow like looping, branching, and jumping can be challenging.

For more information on 'Notification', refer to the documentation here: http://reactivex.io/rxjs/class/es6/Notification.js~Notification.html.

To explore 'materialize', visit the documentation at: http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-materialize

If you need to handle errors without halting your source observable, consider implementing the following approach:

function process(source, success, error) {
  return source.materialize()
    .map(function(notification){
      const value = notification.value;
      if (notification.kind === 'N') {
        return Notification.createNext(success(value));
      }
      if (notification.kind === 'E') {
        return Notification.createNext(error(value));
      }
      if (notification.kind === 'C') {
        return Notification.createComplete();
      }
    })
   .dematerialize()
}

Utilize this function with your source observable by providing the success and error functions to handle streamed values accordingly. This method involves transforming error messages into normal messages and then reverting back to regular operation.

Note that this suggestion is based on experience and hasn't been tested extensively. Please share feedback on its usefulness. I have employed a similar technique multiple times in Rxjs v4, and I believe it can be adapted seamlessly to Rxjs v5.

Answer №2

Breaking the Observable contract means defying its purpose. An Observable is meant to produce values, and once it completes or encounters an error, it should not continue to produce more values.

There are ways to work around this limitation by composing observables properly to resume the stream with a new observable. Using the .catch operator in your observable chain can help create a new observable when an error occurs. However, without more context, it's challenging to provide specific guidance. Additional details would be necessary to offer a relevant example.

Note:

For more information, refer to the Observable contract guide.

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

Is there a way to temporarily pause HTTP calls?

Looking for a solution to this problem I'm facing with the code below: while (this.fastaSample.length > 0) { this.datainputService .saveToMongoDB(this.fastaSample.slice(0, batch)) .subscribe(); } The issue is that I can't send all ...

Issue detected in the console: Angular and Express code linked with status code 200 displaying an error

I am attempting to delete data along with an image connected to that data via an image Id using a get route (since the delete route didn't work out for me). The data is successfully being deleted, but I keep receiving a 200 OK response followed by an ...

Context for Apollo server has not been defined

Following the upgrade to Apollo v4 and migration guide, my project was functioning properly. However, the context is now undefined. const { url } = await startStandaloneServer(server, { listen: { port: 3000 }, context: async ({ req }) => { try ...

What is the appropriate return type for this function in TypeScript?

Seeking clarity on a fundamental TypeScript concept here. I've noticed that Google Cloud examples use JavaScript, and I'm in the process of converting one to TypeScript. Source: https://cloud.google.com/storage/docs/listing-buckets#storage-list ...

exit out of React Dialog using a button

I have a scenario where I want to automatically open a dialog when the screen is visited, so I set the default state to true. To close the dialog, I created a custom button that, when clicked, should change the state to false. However, the dialog does no ...

What could be the reason for TypeScript inferring the generic type as an empty string?

I have developed a React component known as StateWithValidation. import { useStateWithValidation } from "./useStateWithValidation"; export const StateWithValidation = () => { const [username, setUserName, isValid] = useStateWithValidation( ( ...

Attempting to start the server with http-server resulted in a TypeError indicating that Readable.from is not a valid function available

I am currently integrating PWA into my new Angular project. C:\Users\alan_yu\angular-pwa>http-server -p 8080 -c-1 dist/angular-pwa Initializing http-server to serve the files in dist/angular-pwa http-server version: 14.0.0 http-server ...

Angular 6: encountering difficulty in setting up component routes (from root to child) when creating separate modules

As a newcomer to Angular, I'm encountering some difficulties in defining child routes in Angular. I'm not sure where I'm going wrong. When I try to create a separate module for the child components, I run into issues when defining the routes ...

Should beginner node.js developers start with NestJs or should they gain experience with Express first?

After completing a project using the Express JS library on the Mozilla (MDN) training site, I started looking for a more reliable option due to various reasons such as architectural concerns and issues with modern JavaScript features like async-await. That ...

The moduleResolution setting is missing in the tsconfig.json file generated by Next.js TypeScript

Currently, I am in the process of migrating my existing Next.js project to TypeScript. To do this successfully, I have installed various TypeScript related packages by running the following command: npm install --save-dev typescript @types/react @types/nod ...

Uploading a File using Angular HttpClient to CodeIgniter 3 API-Rest

I'm currently facing an issue while attempting to send a file from Angular-CLI to an API-Rest application built in Codeigniter3, as I am receiving an unknown error in response. Angular Code Service: constructor( private http: HttpClient) { } submitI ...

Angular's queryParams do not appear to properly connect with the query parameters

My code seems to have a mistake somewhere, but I can't figure it out. In my [queryParams] = "{allowEdit: server.id == 3 ? 1 : 0}", the params object is empty when I subscribe to it in the edit-server component. Why is it empty and how do I a ...

Issue encountered during an isolated test in Jasmine involving two separate EventEmitters

Currently, I am facing a testing issue with my class. The class has two services that utilize two different EventEmitters; one from a regular event import and the other from @angular/core. The problem arises when I try to import both EventEmitters, as the ...

Tips for incorporating a reference into a styled component div in a React application using TypeScript

Looking to include a reference to a styled component div. Here is the code snippet: const DragAndDrop: React.FC<any> = props => { const divRef= React.createRef(); return ( <Zone ref={divRef}/> ); } Encountering thi ...

Issues with Angular ng-bootstrap tabset component not functioning as expected

{ "name": "ModalWindow", "version": "1.0.0", "repository": { "type": "git", "url": "" }, "scripts": { "build": "webpack --mode production", "start": "webpack-dev-server --mode development --open" }, "license": "MIT", "depend ...

Is there a way to get this reducer function to work within a TypeScript class?

For the first advent of code challenge this year, I decided to experiment with reducers. The following code worked perfectly: export default class CalorieCounter { public static calculateMaxInventoryValue(elfInventories: number[][]): number { const s ...

Vue: Simple ways to retrieve state data in MutationAction

I'm having trouble accessing the state inside @MutationAction Here is the setup I am using: Nuxt.js v2.13.3 "vuex-module-decorators": "^0.17.0" import { Module, VuexModule, MutationAction } from 'vuex-module-decorators' ...

Increase the current version number by adding the release candidate label and making it a prerelease using npm version command

Our team is in the process of streamlining our versioning and build processes for our Angular 2 applications through automation. We are interested in leveraging npm version However, we have encountered difficulty when attempting to add an 'rc' ...

best typescript configuration for node 8 suggested

When configuring TypeScript for use with Node 8, what is the optimal setup? Many tutorials recommend using the following tsconfig.json: { "compilerOptions": { "target": "es6", "module": "commonjs" } } However, it has come to my attention tha ...

Unspecified type for 'props' parameter - a hurdle in Vue 2's composition API

I've hit a roadblock while attempting to integrate TypeScript into an existing Vue 2.6 project. Unfortunately, I'm required to stick with version 2.6 for legacy reasons. I've gone ahead and installed the composition API as a plugin. The err ...