What range should I use for custom error codes in node? - node.js

I'm using meteor and want to throw an error within a template with a custom error code. What values are already taken, and is this an acceptable way of distinguishing between custom errors? I'm only catching these errors within this template, so creating custom error classes seems like overkill.

Im not sure if the built in meteor error will meet your needs, but it provides a way to have clearly defined types of errors without the need to make new error classes.
the code could be something like this:
const ERROR_TYPE_A = 'error-type-a';
// code...
throw new Meteor.Error(ERROR_TYPE_A, "this can be a human readable string, which could be displayed to the user");
in the catching context:
if (err.error === ERROR_TYPE_A){
// switch on type...
}
you could then type check the exception against the constant.
hope that helps.

Related

Mongoose - Difference between Error.ValidationError, and Error.ValidatorError

The question pretty much says it all.
As far as I can tell from the docs, one is for general validation errors (a required field not being included, maxLength being exceeded, etc.).
And one is given as the reason within the other, whenever an error occurs within a custom validator... Is that correct?
If so, which is which? The naming convention used is really confusing here!
After a little more research, and investigation. It seems that all validation type errors (which include Error.CastError errors) always exist within a, Error.ValidationError object. This is the parent object, and itself doesn't really offer much information, other than that validation has failed somewhere along the line.
Within this Error.ValidationError object, can be many other error objects. It's these children that will be instances of Error.ValidatorError (or Error.CastError).
A validation error will therefore look something like:
// When receiving some error, with the variable name "err".
err instanceof mongoose.Error.ValidationError
// true
console.log(err);
errors: {
some_doc_field_name: {} // Possibly an instanceof "Error.ValidatorError"
another_doc_field_name: {} // Possibly an instanceof "Error.CastError"
}
TL;DR:
ValidationError = the parent type of the error.
ValidatorError = one of the potential children types of error it's children can have.

TypeScript best way to restore prototype chain? (Node.js)

I have questions about the Object.setPrototypeOf(this, new.target.prototype) function because of this MDN warning:
Warning: Changing the [[Prototype]] of an object is, by the nature of how modern JavaScript engines optimize property accesses, currently a very slow operation in every browser and JavaScript engine. In addition, the effects of altering inheritance are subtle and far-flung, and are not limited to simply the time spent in the Object.setPrototypeOf(...) statement, but may extend to any code that has access to any object whose [[Prototype]] has been altered.
Because this feature is a part of the language, it is still the burden on engine developers to implement that feature performantly (ideally). Until engine developers address this issue, if you are concerned about performance, you should avoid setting the [[Prototype]] of an object. Instead, create a new object with the desired [[Prototype]] using Object.create().
So what would be the best way to restore the prototype string in TypeScript (Node.js) without using Object.setPrototypeOf(this, new.target.prototype) (but using classes)? This is all because of an error management middleware implemented in Express, in which I need to make use of instanceof to determine the origin of the error and thus return a proper response, but whenever I make a class that extends from Error, the error instanceof Error returns true, but error instanceof CustomError returns false. Doing a little research I found this in the official TypeScript documentation:
The new.target meta-property is new syntax introduced in ES2015. When an instance of a constructor is created via new, the value of new.target is set to be a reference to the constructor function initially used to allocate the instance. If a function is called rather than constructed via new, new.target is set to undefined.
new.target comes in handy when Object.setPrototypeOf or proto needs to be set in a class constructor. One such use case is inheriting from Error in NodeJS v4 and higher
// Example
class CustomError extends Error {
constructor(message?: string) {
super(message); // 'Error' breaks prototype chain here
Object.setPrototypeOf(this, new.target.prototype); // restore prototype chain
}
}
// Results
var CustomError = (function (_super) {
__extends(CustomError, _super);
function CustomError() {
var _newTarget = this.constructor;
var _this = _super.apply(this, arguments); // 'Error' breaks prototype chain here
_this.__proto__ = _newTarget.prototype; // restore prototype chain
return _this;
}
return CustomError;
})(Error);
And I thought okay everything is perfect since the code at the moment of being converted, I suppose that the compiler will take care of that function that is slow and will replace it with another procedure that is more efficient, but to my surprise it's not like that and I'm a little worried about the performance (I'm working on a big project).
I'm using TypeScript version 3.9.6 in Node 14.5.0, these are screenshots of the tests I did:
TypeScript with Node
TypeScript Playground
TypeScript compiler results

Inspect template strings before concatenation

I am generating error messages like so:
throw `Do not recognize eventType '${eventType}', recognized events are ${recognizedEvents}.`;
the problem is recognizedEvents is an object, but it will simply be toString'ed...Anyway, so I could do this:
throw `Do not recognize eventType '${eventType}', recognized events are ${util.inspect(recognizedEvents)}.`;
the problem is not only that it's more verbose - sometimes I simply forget to call util.inspect(). Even TypeScript let's me compile template literals if an object is passed directly. What is a good technique here to make sure objects get inspected to a reasonable depth in the logs?
Would you be more likely to remember to use a tagged template instead of util.inspect within each template string?
function err(strings, eventType, recognizedEvents) {
return `${strings[0]}${eventType}${strings[1]}${util.inspect(recognizedEvents)}`;
}
throw err`Do not recognize eventType '${eventType}', recognized events are ${recognizedEvents}.`;
Combined with #JackBashford's suggestion of using JSON.stringify instead of util.inspect, you can get the object stringified as deep as it can be.

Nice Error Messages for "no viable alternative at input '<EOF>'" in ANTLR4

I want to show more beautiful error message to my users.
For example if someone types integer i= the error message no viable alternative at input '<EOF>' appears. That's totally fine and predictable due to my grammar rules but I'm figuring out ways to improve those messages. If the = is missing in the example above the message changes to mismatched input '<EOF>' expecting '='. Again predictable but I can do more stuff on things like this in my code than on a general input error.
Should I catch them in the code and try to evaluate which cases is meant? Or is there a better way to handle this?
Typically you'd create your own error listener and add it to the parser where you can deal with the error yourself. For that remove any existing error listeners (one for the console is automatically registered by default), by calling parser.removeErrorListeners();. Define an own error listener class derived from BaseErrorListener and add an instance of that to your parser via parser.addErrorListener(yourListener);. You can see an example of such a custom error listener in the ANTLR runtime (search for XPathLexerErrorListener). Override the syntaxError method and use the provided info to generate your own error message. There is already a message passed in to this method (in addition to other stuff like line + char position, exception etc.), which you cannot customize as it comes directly from generated code. So best is probably to leave that alone and start from scratch (the passed in exception is your best option you have).

Common php functions in hack

I decided to start a new project to get into hacklang, and after fixing some if the problems I initially ran into transitioning from php habits, I ran into the following errors:
Unbound name: str_replace
Unbound name: empty
Doing some research I found that this is due to using 'legacy' php which isn't typechecked, and will error with //strict.
That's fine and all, empty() was easy enough to replace, however str_replace() is a bit more difficult.
Is there an equivalent function that will work with //strict? Or at least something similar.
I'm aware that I could use //decl but I feel like that defeats the purpose in my case.
Is there at least any way to tell which functions are implemented in hack and which are not in the documentation as I couldn't find one?
For reference (though it isn't too relevant to the question itself), here is the code:
<?hh //strict
class HackMarkdown {
public function parse(string $content) : string {
if($content===null){
throw new RuntimeException('Empty Content');
}
$prepared = $this->prepare($content);
}
private function prepare(string $contentpre) : Vector<string>{
$contentpre = str_replace(array("\r\n","\r"),"\n",$contentpre);
//probably need more in here
$prepared = Vector::fromArray(explode($contentpre,"\n"));
//and here
return $prepared;
}
}
You don't need to change your code at all. You just need to tell the Hack tools about all the inbuilt PHP functions.
The easiest way to do this is to download this folder and put it somewhere in your project. I put it in a hhi folder in the base of my project. The files in there tell Hack about all the inbuilt PHP functions.
Most of them don't have type hints, which can lead to Hack thinking the return type of everything is mixed instead of the actual return, that is actually correct in most cases as, for example, str_replace can return either a string or a bool. However, it does stop the "unbound name" errors, which is the main reason for adding them.

Resources