I'd like to have my unit tests assert that a particular function call throws an AssertionError specifically when expected, rather than that it throws an exception at all. The assertion library (expect) supports such a thing by passing an exception constructor in, but I can't seem to find where, if anywhere, the AssertionError constructor is exported. Is it intended to be an internal class only and not exposed to us? The docs contain numerous references to it, but no links.
I have a super hacky way:
let AssertionError;
try {
const assert = require("assert");
assert.fail();
}
catch (ex) {
AssertionError = ex.constructor;
}
but I'm hoping there's a better way.
Assertion error class is defined here:
assert.AssertionError
*It can be useful while testing and AsserionError is expected result:
assert.throws( FunctionThatShouldThrow_AssertionError, assert.AssertionError )
After a research in the Nodejs github repo, I can tell you it is here:
https://github.com/nodejs/node/blob/c75f87cc4c8d3699e081d37bb5bf47a70d830fdb/lib/internal/errors.js
AssertionError is defined like this :
class AssertionError extends Error {
constructor(options) {
if (typeof options !== 'object' || options === null) {
throw new exports.TypeError('ERR_INVALID_ARG_TYPE', 'options', 'object');
}
var { actual, expected, message, operator, stackStartFunction } = options;
if (message) {
super(message);
} else {
if (actual && actual.stack && actual instanceof Error)
actual = `${actual.name}: ${actual.message}`;
if (expected && expected.stack && expected instanceof Error)
expected = `${expected.name}: ${expected.message}`;
if (util === null) util = require('util');
super(`${util.inspect(actual).slice(0, 128)} ` +
`${operator} ${util.inspect(expected).slice(0, 128)}`);
}
this.generatedMessage = !message;
this.name = 'AssertionError [ERR_ASSERTION]';
this.code = 'ERR_ASSERTION';
this.actual = actual;
this.expected = expected;
this.operator = operator;
Error.captureStackTrace(this, stackStartFunction);
}
}
If I were you, I would not redefined AssertionError, that is very, very hacky. I think your best bet is to extend that class to MyAssertionError or to create a twin than extends error.
Hope that helps!
Related
The code is like this:
class MyClass {
getValue() {
// some code here...
}
}
const IS_ENABLED = process.env.IS_ENABLED || false;
const myClass = IS_ENABLED ? new MyClass() : null;
function getValue() {
if (!IS_ENABLED) return false;
return myClass.getValue();
}
Now at this point, TypeScript is giving error (for myClass.getValue()):
Object is possibly 'null'.
But, since I've checked the condition, I'm sure it's not null.
Is there any way for TypeScript to handle it?
Typescript will not keep track of variables that are related in this way. There are a number of patterns that act as type guards and change the type of a variable.
In this case since IS_ENABLED and myClass are very much related, you can just check the if myClass is undefined.
const IS_ENABLED = process.env.IS_ENABLED || false;
const myClass = IS_ENABLED ? new MyClass() : null;
function getValue() {
if (!myClass) return false;
return myClass.getValue();
}
Or you could use a discriminated union (this might be useful if you have multiple myClass type like varaibles):
const config = (process.env.IS_ENABLED || false) ? {
IS_ENABLED: true as const,
myClass: new MyClass(),
myClass2: new MyClass()
} : {
IS_ENABLED: false as const,
}
function getValue() {
if (!config.IS_ENABLED) return false;
config.myClass2.getValue();
return config.myClass.getValue();
}
Type Guards allow you to narrow down the type of an object within a conditional block.
You can use instanceof to make Typescript knows its type.
const IS_ENABLED = process.env.IS_ENABLED || false;
const myClass = IS_ENABLED ? new MyClass() : null;
function getValue() {
if (!IS_ENABLED) return false;
if (myClass instanceof MyClass) {
return myClass.getValue();
}
return false;
}
For details please check this.
I am developing a small page/router component on a website using Angular 7 and its CLI. At one point I need to check if the user has allowed flash, I do this by doing so:
checkFlash() {
var hasFlash = false;
try {
hasFlash = Boolean(new ActiveXObject("ShockwaveFlash.ShockwaveFlash"));
} catch (exception) {
hasFlash = "undefined" != typeof navigator.mimeTypes["application/x-shockwave-flash"];
}
return hasFlash;
}
I found this off here, and it works great, but now as I am cleaning up my application I am noticing that Angular doesn't seem to like this, in fact, it says that ActiveXObject isn't defined, yet it still works.
Super confused...
I tried linking an actual flash object like so $('embed[type="application/x-shockwave-flash"]') or $('embed[type="application/x-shockwave-flash"]')[0] but had no luck, it always returned true.
I tried installing extra npm(s) including ones like activex-support and activex-data-support as well as their #types cousins. After setting them up I found out that they did nothing to help my case.
Here are the exact errors the CLI & VScode-Intellisense gave me:
VScode:
[ts] 'ActiveXObject' only refers to a type, but is being used as a value here. [2693]
any
CLI:
ERROR in src/app/games/games.component.ts(51,30): error TS2304: Cannot find name 'ActiveXObject'.
It doesn't throw this error when ran inside plain JS, but I've looked around and can't seem to figure out how to run pure JS inside Angular 2 (7). Also looked here with no luck.
Please help, completely lost here.
EDIT: Found the fix -->
The answer was here listed inside the comments (will need to make minor changes)(shown below)
change from:
checkFlash() {
var hasFlash = false;
try {
hasFlash = Boolean(new ActiveXObject("ShockwaveFlash.ShockwaveFlash"));
} catch (exception) {
hasFlash = "undefined" != typeof navigator.mimeTypes["application/x-
shockwave-flash"];
}
return hasFlash;
}
to:
function checkFlash() {
var hasFlash = false;
try {
var flash =
navigator.mimeTypes &&
navigator.mimeTypes["application/x-shockwave-flash"]
? navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin
: 0;
if (flash) hasFlash = true;
} catch (e) {
if (navigator.mimeTypes["application/x-shockwave-flash"] != undefined)
hasFlash = true;
}
return hasFlash;
}
This issue with ActiveXObject can be solve as shown below:
Goto your tsconfig.json file and add the 'scripthost' library.
Then recompile your application.
"lib": [
"es2017",
"dom",
"scripthost"
]
The answer was here listed inside the comments (will need to make minor changes)(shown below)
change from:
checkFlash() {
var hasFlash = false;
try {
hasFlash = Boolean(new ActiveXObject("ShockwaveFlash.ShockwaveFlash"));
} catch (exception) {
hasFlash = "undefined" != typeof navigator.mimeTypes["application/x-
shockwave-flash"];
}
return hasFlash;
}
to:
function checkFlash() {
var hasFlash = false;
try {
var flash =
navigator.mimeTypes &&
navigator.mimeTypes["application/x-shockwave-flash"]
? navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin
: 0;
if (flash) hasFlash = true;
} catch (e) {
if (navigator.mimeTypes["application/x-shockwave-flash"] != undefined)
hasFlash = true;
}
return hasFlash;
}
I am currently trying to handle exceptions and errors in a NodeJS app which will be used for critical information. I need a clean error management !
I've been wondering if there is something similar to Java Exceptions encapsulation.
I'm explaning.
In Java you can do something like that :
try {
// something that throws Exception
} catch (Throwable t) {
throw new Exception("My message", t);
}
That allows you to decide when to log your exception and you get the whole stack trace and call path !
I would like to know if there is a way to do the same in NodeJS because logging at every step seems not to be the right way of doing things.
Thank you.
You should look at this module :
https://www.npmjs.com/package/verror
Joyent quote it on his error management best pratices : https://www.joyent.com/developers/node/design/errors
At Joyent, we use the verror module to wrap errors since it's
syntactically concise. As of this writing, it doesn't quite do all of
this yet, but it will be extended to do so.
It allow you to get details on error message. And tracking the step of the error.
And also hide details to the client with wrapped error : WError() who returns only the last error message.
I answer my own question to explain what i finaly did to have the wanted encapsulation.
I used https://www.npmjs.com/package/verror as Sachacr suggested.
Then I extended it that way :
my_error.js :
var VError = require('verror');
var _ = require('lodash');
function MyError() {
var args = [];
var httpErrorCode;
var cause;
if (arguments.length > 0) {
var lastArgumentIndex = [arguments.length];
cause = manageCause(lastArgumentIndex, arguments);
httpErrorCode = manageHttpCode(lastArgumentIndex, arguments);
for (var i = 0; i < lastArgumentIndex; i++) {
args[i] = arguments[i];
}
}
this.__proto__.__proto__.constructor.apply(this, args);
if (cause) {
if (this.stack) {
this.stack += '\n' + cause.stack;
} else {
this.stack = cause.stack;
}
}
this.httpErrorCode = httpErrorCode;
}
MyError.prototype.__proto__ = VError.prototype;
function manageCause(lastArgumentIndex, arguments) {
if (lastArgumentIndex[0] > 0
&& arguments[lastArgumentIndex[0] - 1] instanceof Error) {
lastArgumentIndex[0]--;
return arguments[lastArgumentIndex[0]];
}
}
function manageHttpCode(lastArgumentIndex, arguments) {
if (lastArgumentIndex[0] > 0
&& _.isNumber(arguments[lastArgumentIndex[0] - 1])) {
lastArgumentIndex[0]--;
return arguments[lastArgumentIndex[0]];
}
}
module.exports = MyError;
It allows me to use it easily in my code :
var MyError = require('./my_error.js');
function withErrors() {
try {
// something with errors
} catch (err) {
// This is the same pattern as VError
return new MyError("My message", err, 401);
}
}
function somethingToDo(req, res) {
var result = withErrors();
if (result instanceof MyError) {
logger.warn(result);
res.status(result.httpErrorCode).send(result.message).end();
return
}
}
That way, i hace a nice stack trace with call path and every line involved in error/exception.
Hope it will help people, cause i searched a looooong time :)
EDIT : I modified my MyError class to add HTTP Error codes and clean arguments management.
You should be able to do something like:
funtion exception(message, error) {
this.message = message;
this.stacktrace = error.stack;
}
try {
if(someData == false)
throw new exception("something went wrong!", new Error());
}
catch(ex) {
console.log(ex.message);
console.log(ex.stacktrace);
}
You can then throw your own custom exception instance containing whatever debugging info you need.
EDIT: added stack trace to exception object
I have a library that connects to a remote API:
class Client(access_token) {
void put(key, value, callback);
void get(key, callback);
}
I want to set up a Node.js REPL to make it easy to try things out:
var repl = require('repl');
var r = repl.start('> ');
r.context.client = new Client(...);
The problem is that an asynchronous API is not convenient for a REPL. I'd prefer a synchronous one that yields the result via the return value and signals an error with an exception. Something like:
class ReplClient(access_token) {
void put(key, value); // throws NetworkError
string get(key); // throws NetworkError
}
Is there a way to implement ReplClient using Client? I'd prefer to avoid any dependencies other than the standard Node.js packages.
You can synchronously wait for stuff with the magic of wait-for-stuff.
Based on your example specification:
const wait = require('wait-for-stuff')
class ReplClient {
constructor(access_token) {
this.client = new Client(access_token)
}
put(key, value) {
return checkErr(wait.for.promise(this.client.put(key, value)))
}
get(key) {
return checkErr(wait.for.promise(this.client.get(key)))
}
}
const checkErr = (maybeErr) => {
if (maybeErr instanceof Error) {
throw maybeErr
} else {
return maybeErr
}
}
In this c# code I need to convert the userName value from string to int type.
Is anyone know please help me. I have got error as a compilation error "Cannot convert lambda expression to type 'int' because it is not a delegate type" like this.
ShoppingCartPartRecord cartRecord = null;
try {
cartRecord = _shoppingCartRepository.Get(r => r.Username == userName);
}
catch (InvalidOperationException ex) {
if (ex.Message == "Sequence contains more than one element") {
var badCarts = _shoppingCartRepository.Table.Where(x => x.Username == userName);
foreach (var shoppingCartPartRecord in badCarts) {
_shoppingCartRepository.Delete(shoppingCartPartRecord);
}
}
}
Thank you in advance.
Without the source to your repository we can only guess at what the methods do.
From the errors you are describing the get function expects either an index into an array or an integer primary key and so is the wrong function
You should be able to change the code as follows to achieve the desired effect
ShoppingCartPartRecord cartRecord = null;
try {
cartRecord = _shoppingCartRepository.Table.Single(r => r.Username == userName);
}
catch (InvalidOperationException ex) {
if (ex.Message == "Sequence contains more than one element") {
var badCarts = _shoppingCartRepository.Table.Where(x => x.Username == userName);
foreach (var shoppingCartPartRecord in badCarts) {
_shoppingCartRepository.Delete(shoppingCartPartRecord);
}
}
}