How do I fetch-mock an accurate server error? - javascript

The issue:
fetchmock
fetchMock.get('glob:https://*/server-api-uri', () => {
throw { example: 'error' }
})
Source JS file:
exampleServerCall().catch(error => {
console.log(error) // error = "[ object object ]" :(
})
So my catch statements are returning with a useless "[ object object ]" string when what I really want is access to the full mocked server error.

After reading the MDN docs for throw, I found documentation for how to throw a custom object in a throw handler.
You need to do it by creating a custom class object.
fetchmock
class CustomError {
example = 'error'
}
fetchMock.get('glob:https://*/server-api-uri', () => {
throw new CustomError()
})
source JS file:
exampleServerCall().catch(error => {
console.log(error) // error = { example: 'error' } :D
})

Related

nodejs assert module: assert.throws only returns "undefined"

As found in the official documentation. Trying the below code would only result in
undefined.
assert.throws(
() => {
throw new Error('Wrong value');
},
Error
);
I was able to find some issues about the arrow functions => not working in the statement but changing that to function() doesn't change a thing. As in the link above my node version is the exact same version.
What am I missing?
EDIT:
console.log(assert.throws(
() => {
throw new Error('Wrong value');
},
Error
)) // this will log "undefined"
let result = assert.throws(
() => {
throw new Error('Wrong value');
},
Error
);
console.log(result); // as well as this
Many thanks
So, as #tkausl has stated in the comments (thanks by the way.) assert.throws "asserts that the passed function throws".
In order to achieve my desired result, I had to do this:
console.log(() => {
let error;
try {
// function that may throw an error
} catch (e) {
error = e;
}
// and than do something with 'error' and return a value
return error
}())

Firebase Functions How To Handle Errors Properly [duplicate]

This question already has an answer here:
Google Cloud Functions - warning Avoid nesting promises promise/no-nesting
(1 answer)
Closed 3 years ago.
NOTE: this question is mainly about error handling, and if this is an ok approach, not about nesting promises, please read before closing
Since there are currently no error codes for services like firestore and firebase database, i'm using a system to know where the function failed and to handle error accordingly, simplified version below:
exports.doStuff = functions.https.onCall((data, context) => {
return [promise doing stuff goes here].catch(error => { throw new Error('ERROR0') })
.then(result => {
return [promise doing stuff goes here, needs result of previous promise]
.catch(error => { throw new Error('ERROR1') })
})
.then(result => {
return [promise doing stuff goes here, needs result of previous promise]
.catch(error => { throw new Error('ERROR2') })
})
.then(result => {
//inform client function successful
return {
success: true
}
})
.catch(error => {
if (error !== null) {
switch (error.message) {
case 'ERROR0':
//do stuff
throw new functions.https.HttpsError('unknown', 'ERROR0');
case 'ERROR1':
//do stuff
throw new functions.https.HttpsError('unknown', 'ERROR1');
case 'ERROR2':
//do stuff
throw new functions.https.HttpsError('unknown', 'ERROR2');
default:
console.error('uncaught error: ', error);
throw error;
}
}
});
});
the thing is, for each .catch() inside each returned promise, i'm getting the following warning: warning Avoid nesting promises
so my question is, is there a better way to handle errors?
Ultimately it's a style recommendation to prevent bizarre and hard to recognise errors. Most of the time a rewrite can eliminate the warning. As an example, you could rewrite your code as the following whilst retaining the same functionality.
exports.doStuff = functions.https.onCall(async (data, context) => {
const result1 = await [promise doing stuff goes here]
.catch(error => {
throw new functions.https.HttpsError('unknown', 'ERROR0', { message: error.message } )
});
const result2 = await [promise based on result1 goes here]
.catch(error => {
throw new functions.https.HttpsError('unknown', 'ERROR1', { message: error.message } )
});
const result3 = await [promise based on result1/result2 goes here]
.catch(error => {
throw new functions.https.HttpsError('unknown', 'ERROR2', { message: error.message } )
});
return {
success: true
};
});
Lastly, rather than using unknown everywhere, you could use one of several possible values for the first argument whilst passing in whatever supporting information you need as the third argument (as shown above where I pass through the original error message).

jasmine testing uncaught error event handler

I am having difficulties testing a new package that I am writing with jasmine.
The package idea is to create a listener for error or "uncaughtException" (in node) and give it a callback to work if there is such event.
describe('AllErrorHandler', function () {
it('error is passed to the callback', function () {
const error = new Error("testError");
const callbackError;
let errorHandler = new AllErrorHandler((error) => {
callbackError = error;
})
throw error;
expect(callbackError).toBe(error);
})
})
How can I make this right?
First of all, error is not a function. You need throw error not throw error().
Then the line after you throw is not reachable (unless you wrap the whole thing with try-catch :) which kinda beats the whole point of the test).
You could try something like this. But I'm not 100% this would work.
describe('AllErrorHandler', function () {
it('error is passed to the callback', function (done) {
const error = new Error("testError");
let errorHandler = new AllErrorHandler((arg1) => {
expect(arg1).toBe(error);
done();
});
setTimeout(() => {
throw error;
}, 0)
})
})

throw error inside rxjs Observable

I'm trying to throw an error inside a rxjs Observable
new Observable(subscriber => {
Observable.throw("error1");
return Observable.throw("error2");
})
.subscribe(
() => {},
err => console.error(err)
);
error 1 is not caught.
error2 gives a compilation error:
Argument of type '(this: Observable<{}>, subscriber: Subscriber<{}>) => ErrorObservable<string>' is not assignable to parameter of type '(this: Observable<{}>, subscriber: Subscriber<{}>) => TeardownLogic'. Type 'ErrorObservable<string>' is not assignable to type 'TeardownLogic'
what is the proper way to throw an error inside an observable?
Use Subscriber.error:
new Rx.Observable(subscriber => {
subscriber.error("error1");
subscriber.error("error2"); // not called because a stream will be finalized after any error
})
.subscribe(
() => {},
err => console.error(err)
);
<script src="https://unpkg.com/rxjs/bundles/Rx.min.js"></script>
When using new Observable() or Observable.create() you can push the error directly to the subscriber (observer):
Observable.create(subscriber => {
subscriber.error(new Error("error1"));
})
.subscribe(
() => {},
err => console.log(err.message)
);
The anonymous function passed to new Observable() can optionally return an unsubscribe callback. That's why it gives you the error because you're returning an Observable.
Using Observable.throw("error1") is usually not necessary. This is just an Observable that only emits an error and nothing more. You could use it for example like the following:
Observable.create(subscriber => {
subscriber.next('whatever');
})
.merge(Observable.throw(new Error("error2")))
.subscribe(
() => {},
err => console.log(err.message)
);
See live demo: https://jsbin.com/fivudu/edit?js,console
In v6 and higher you want to import throwError, that Observable.throw static method is an unfortunate necessity leftover from v5 compat.
import { throwError } from 'rxjs';
throwError('hello');
Source: https://github.com/ReactiveX/rxjs/issues/3733#issuecomment-391427430
With an observable you created yourself, you have access to the observer.error() method.
const obs = Observable.create(observer => {
// Emit a value.
observer.next("hello");
// Throw an error.
observer.error("my error");
});
Note: if you're using RxJS 4, you'll have to use onNext() and onError() instead.

Catch Error Type in Bluebird Not Working

I have a custom error class:
class NetworkError extends Error {
constructor() {
super('Network Error');
this.name = 'NetworkError';
}
}
And I want to handle it specifically:
import {NetworkError} from '../../common/errors';
someFunc().catch(NetworkError, err => {
// this is missed
}).catch(err => {
// this is hit
});
But it's skipping my custom catch and hitting the general catch. If I change it like so, it works:
someFunc().catch({name: 'NetworkError'}, err => {
// this is hit
}).catch(err => {
// this is missed
});
Obviously the first way is preferred. What am I missing here?
As #loganfsmyth suggested in the question comments, it's a Babel limitation. This answer does the trick:
Why doesn't instanceof work on instances of Error subclasses under babel-node?

Categories

Resources