2

There is a function that handles response from scan:

export const handleScanResponse = (
  scanResponse: IScanResponse,
  visitors: IVisitor[]
): Promise<IVisitor | any> => {
  return new Promise((resolve, reject) => {
    if (!scanResponse || scanResponse.errorDesc !== "SUCCESS")
      throw new Error("Scane response is empty!");

    const found = visitors.find((p: IVisitor) => {
      if (scanResponse && "qrcode" in scanResponse) {
        return (
          p.code && p.code.toLowerCase() === scanResponse.qrcode.toLowerCase()
        );
      } else {
        return (
          p.document_number &&
          scanResponse.document_number &&
          p.document_number.toLowerCase() ===
            scanResponse.document_number.toLowerCase()
        );
      }
    });

    if (found) resolve(found);

    reject(scanResponse);
  }).catch((e) => console.log(e));
};

I tried to resolve, reject in cases when user was found and not found in array. Otherwise try to throw an exeption.

Using is:

  handleScanResponse(
      scanerResponseMockup,
      this.visitorsService.visitors$.getValue()
    ).then(
      (foundVisitor) => this.visitorWasFound(foundVisitor),
      (scanResponse) => this.visitorNotFound(scanResponse)
    );

How to do that properly? Why despite exception I always go to .then( (foundVisitor) => this.visitorWasFound(foundVisitor)?

  • In a Promise constructor, you have to `resolve()` or `reject()`. In `.then()` and `.catch()` callbacks, you have to `return` or `throw`. – Roamer-1888 Jan 10 '21 at 01:34

1 Answers1

3

When a .catch is added to the end of a Promise chain, and something throws, the whole Promise chain will resolve rather than reject. Your

.catch((e) => console.log(e));

is turning rejections into resolutions; the Promise that handleScanResponse returns will never reject.

Only catch errors at a place that you can handle them reasonably. Here, just leave out the .catch, and it should work as desired; this way, a rejected Promise will simply percolate up to the caller, and your

).then(
  (foundVisitor) => this.visitorWasFound(foundVisitor),
  (scanResponse) => this.visitorNotFound(scanResponse)
);

will be able to deal with it.

That said, there doesn't appear to be anything asynchronous going on in this code here. I'd recommend removing the Promise entirely.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • So, when to use catch if it appears? – –  Jan 09 '21 at 23:49
  • You use catch to catch an error. But that's not what you want to in your method. There you want to throw. You catch an error where you want to deal with it. – trollkotze Jan 09 '21 at 23:51
  • 1
    @AliceMessis You should `.catch` only when you can reasonably deal with the error. For example, if you really need the Promise, you could have a `.catch((scanResponse) => this.visitorNotFound(scanResponse))` - there, you can take a good useful action in response to the error. In contrast, having a `.catch` that just logs the error isn't really useful. – CertainPerformance Jan 09 '21 at 23:51
  • @AliceMessis Also check this out: https://stackoverflow.com/q/24662289 Often you'll want to have `.catch(` instead of `.then(onSuccess, onFail)`. – CertainPerformance Jan 09 '21 at 23:52