Open 2234839 opened 3 years ago
I like this idea, but it seems much more useful if this information could be propagated by typescript, so that a function which calls something annotated with @throws
and doesn't catch is also considered as throwing.
Something like typescript-eslint/no-floating-promises would be interesting. In this rule unhandled promises shows an error on vscode.
Throw types are the one thing I still find myself wanting in TypeScript. Sometimes the types can get a little unwieldy, but there are very few things these days that you just outright can't express in the latest TypeScript versions. The types might be complicated, but almost anything is possible. Really makes the lack of throw/catch typings feel like a pretty big hole.
function getFriend(name: string): Friend, throws ReferenceError {
const friend = friends.get(name);
if (!friend) throw new ReferenceError("I don't know them!");
return friend;
}
try {
getFriend("aslilac")
} catch (error) {
// typeof error would be inferred as ReferenceError
}
I manage a Typescript app that is built using Firestore and Firebase Functions, a NoSQL database and serverless app infrastructure respectively. Firestore provides a pretty handy async API for putting stuff in a database.
async function putStuff(theStuff: any) {
// Optionally do data validation here
await firestore.collection(...).doc(...).set( theStuff );
}
I then wrap this stuff in a Cloud Function.
export my_function = functions.https.onCall(async (data, context) => {
await putStuff(data);
return 'Stuff has been put.';
})
The Firestore function call may throw an error in some circumstances, which then causes putStuff
to fail. Following that, my Cloud Function throws an error back to the client. Though my client would ordinarily display a useful note, Cloud Function would generate a '500 INTERNAL' error as a default to the user which is not very useful.
My issue is not pertaining to Cloud Functions itself, as the better solution is to use a try/catch block on my async function and handling that in a user-friendly manner.
export my_function = functions.https.onCall(async (data, context) => {
try {
await putStuff(data);
} catch (e) {
return `Sorry, we cannot put the stuff. Error ${e}`;
}
return 'Stuff has been put.';
})
I do think ensuring that a function has a try/catch block is something that should be enforced at the compiler, under a particular optional flag, so that it signals to particular developers that there is code that should be handled before your execution returns to the framework. Particularly in a Node ecosystem moreso than other languages, the employment of many frameworks means that a higher-level solution would not be as scalable.
@throws looks like a Decorator
So I would like to see something more like a type, for example: Throws
Are you aware of TSDoc and its definition of the TSDoc @throws tag? Better support and tooling for TSDoc (e.g. eslint TypeScript rules that consider TSDoc tags as defined in the standard) could resolve or at least mitigate this problem.
Suggestion
Use
@throws
to mark the corresponding error on the method in the .d.ts file in the lib directoryš Search Terms
@throws
jsdoc
comments
ā Viability Checklist
My suggestion meets these guidelines:
ā Suggestion
Use
@throws
to mark the corresponding error on the method in the .d.ts file in the lib directoryš Motivating Example
š» Use Cases
want to be able to write code when you know that you need to beware of these unpredictable behavior