cast Error for use in TypeScript in catch clausule
npm install cast-errorcast Error for use in TypeScript in catch clause
!extending





language: !English
also available in:

``sh`
$ npm install cast-error
The main goal is to have handy way to receive typed Errors y _Typescript_.
In one hand in _Typescript_ when you use catch(err) the variableerr is of type unknown (formerly any). That's why you cannoterr.code
write for SystemErrors (formerly you can but tscerr.code_num
did not warn you if you make a typo like )
In the other hand in _Javascript_ you can throw any variable
regardless of its type. You can even throw null. Then it isn'terr.message
safe to write .
With cast-error this problems are solved in a fancy and efficient
way.
Instead of writing this:
with cast-error you can write:
`ts
try{
somethingCanGoWrong();
}catch(err){
var error = castError.unexpected(err); // implicit console.err because is unexpected
throw err;
}
try{
await fsPromise.unlink('/tmp/aFile.txt');
}catch(err){
var error = castError.expected(err)
if(error.code!='ENOENT') throw err; // code exists in error because is a SystemError
}
`
The main use cases of try/catch are:
1. To register unexpected error conditions in a way that the programmers
can later identify and correct the bug.
2. To warn the users that there is a problem with their input data.
3. To handle an exceptional and recoverable situation.
It is possible to hook and centralize the way to log error in every catchsetLogFunction
setting the log function with and then call unexpected
in the main cycle and in all points where special behavior is needed.
`ts
function initializeSystem(){
//... other inits...
var attributes = {code:true,err_num:true,cause:true};
type MyGlobalError = Error & {[k in keyof typeof attributes]: any}
castError.setLogFunction(function(context:string, error:MyGlobalError){
console.log('*',context);
var attr: keyof typeof attributes;
for(attr in attributes){
console.log(attr,':',error[attr])
}
})
}
// In the main cycle
catch(err){
throw castError.unexpected(err);
}
// In a function with special needs:
function getStream(name:string){
try{
const fd = await fs.open(name)
var stream = fd.createReadStream()
this.decorateStream(stream);
return stream;
}catch(err){
var error = unexpected(err)
console.log('opening stream',name,'in',this.context(error));
throw error;
}
}
`
In some cases, we need to warn users if there are problemas with their input data.
For example, if the user wants to delete a file, and the system doesn't find the file it must warn the user.
In Node.js fs.exists is deprecated. In the documentation
is clear that the way is to use the file and capture the error to know if
the file was not found:
`ts
import * as fs from 'fs/promises';
import {expected} from 'cast-error';
function openFileAndProcess(filename:string){
try{
var stream = fs.createReadStream(filename)
var result = process(stream);
return result;
}catch(err){
var error = expected(err);
if(error.code=='ENOENT'){
return {
ok:false,
message:'file not found'
}
}
throw error;
}
}
`
There are many caveats to observe:
1. If the system is a typical web application is reasonable to think that
there is a table with the names of the files that can be delete by the user.
If opening (or deleting) a file that is suppose to exists, any error is
an unexpected error. And, because of that, is part of the Case 1.
2. Not all programs are the typical web application. A program can be
a command line one or an administration web application. In these cases,
the _file table_ may be not exists.
3. In any case if it is a web application is mandatory to take care of
attackers. So in the error messages the system shouldn't send more
information that what the user can know.
4. If there no validations to a whitelist there be other validations:
the folder, the type of file (or its extension), and the logical ownership of the file.
_[... in progress ...]_
`ts``