I find this so fiddly! I love TypeScript and will continue to use it if there's a choice. But I just wanted to write a simple async function wrapper and I had to Google for it and nothing was quite right. Here's my simple solution, as an example:
function wrappedAsyncFunction<T>(
fn: (...args: any[]) => Promise<T>
): (...args: any[]) => Promise<T> {
return async function(...args: any[]) {
console.time("Took");
try {
return await fn(...args);
} catch(error) {
console.warn("FYI, an error happened:", error);
throw error;
} finally {
console.timeEnd("Took");
}
};
}
What I use it for is to wrap my Firebase Cloud Functions so that if any error happens, I can send that error to Rollbar. In particular, here's an example of it in use:
diff --git a/functions/src/cleanup-thumbnails.ts b/functions/src/cleanup-thumbnails.ts
index 46bdb34..a3e8d54 100644
--- a/functions/src/cleanup-thumbnails.ts
+++ b/functions/src/cleanup-thumbnails.ts
@@ -2,6 +2,8 @@ import * as admin from "firebase-admin";
import * as functions from "firebase-functions";
import { logger } from "firebase-functions";
+import { wrappedLogError } from "./rollbar-logger";
+
const OLD_DAYS = 30 * 6; // 6 months
// const ADDITIONAL_DAYS_BACK = 5;
// const ADDITIONAL_DAYS_BACK = 15;
@@ -9,7 +11,7 @@ const PREFIX = "thumbnails";
export const scheduledCleanupThumbnails = functions.pubsub
.schedule("every 24 hours")
- .onRun(async () => {
+ .onRun(wrappedLogError(async () => {
logger.debug("Running scheduledCleanupThumbnails");
...
And my wrappedLogError
looks like this:
export function wrappedLogError<T>(
fn: (...args: any[]) => Promise<T>
): (...args: any[]) => Promise<T> {
return async function(...args: any[]) {
try {
return await fn(...args);
} catch (error) {
logError(error);
throw error;
}
};
}
I'm not sure it's the best or correct way to do it, but it seems to work. Perhaps there's a more correct solution but for now I'll ship this because it seems to work fine.