diff --git a/keyserver/src/creators/account-creator.js b/keyserver/src/creators/account-creator.js --- a/keyserver/src/creators/account-creator.js +++ b/keyserver/src/creators/account-creator.js @@ -26,6 +26,7 @@ import { threadTypes } from 'lib/types/thread-types-enum.js'; import { ServerError } from 'lib/utils/errors.js'; import { values } from 'lib/utils/objects.js'; +import { ignorePromiseRejections } from 'lib/utils/promises.js'; import { reservedUsernamesSet } from 'lib/utils/reserved-users.js'; import { isValidEthereumAddress } from 'lib/utils/siwe-utils.js'; @@ -45,7 +46,6 @@ fetchKnownUserInfos, } from '../fetchers/user-fetchers.js'; import { verifyCalendarQueryThreadIDs } from '../responders/entry-responders.js'; -import { handleAsyncPromise } from '../responders/handlers.js'; import { searchForUser } from '../search/users.js'; import { createNewUserCookie, setNewSession } from '../session/cookies.js'; import { createScriptViewer } from '../session/scripts.js'; @@ -189,7 +189,9 @@ ...messageInfos, ]; - handleAsyncPromise(createAndSendReservedUsernameMessage([request.username])); + ignorePromiseRejections( + createAndSendReservedUsernameMessage([request.username]), + ); return { id, @@ -287,7 +289,9 @@ const messageDatas = [...ashoatMessageDatas, ...privateMessageDatas]; await Promise.all([createMessages(viewer, messageDatas)]); - handleAsyncPromise(createAndSendReservedUsernameMessage([request.address])); + ignorePromiseRejections( + createAndSendReservedUsernameMessage([request.address]), + ); return id; } diff --git a/keyserver/src/creators/message-creator.js b/keyserver/src/creators/message-creator.js --- a/keyserver/src/creators/message-creator.js +++ b/keyserver/src/creators/message-creator.js @@ -21,7 +21,7 @@ import { redisMessageTypes } from 'lib/types/redis-types.js'; import { threadPermissions } from 'lib/types/thread-permission-types.js'; import { updateTypes } from 'lib/types/update-types-enum.js'; -import { promiseAll } from 'lib/utils/promises.js'; +import { promiseAll, ignorePromiseRejections } from 'lib/utils/promises.js'; import createIDs from './id-creator.js'; import type { UpdatesForCurrentSession } from './update-creator.js'; @@ -41,7 +41,6 @@ import { fetchServerThreadInfos } from '../fetchers/thread-fetchers.js'; import type { Device, PushUserInfo } from '../push/send.js'; import { sendPushNotifs, sendRescindNotifs } from '../push/send.js'; -import { handleAsyncPromise } from '../responders/handlers.js'; import type { Viewer } from '../session/viewer.js'; import { earliestFocusedTimeConsideredExpired } from '../shared/focused-times.js'; import { publisher } from '../socket/redis.js'; @@ -191,9 +190,9 @@ if (!viewer.isScriptViewer) { // If we're not being called from a script, then we avoid awaiting // postMessageSendPromise below so that we don't delay the response to the - // user on external services. In that case, we use handleAsyncPromise to - // make sure any exceptions are caught and logged. - handleAsyncPromise(postMessageSendPromise); + // user on external services. In that case, we use ignorePromiseRejections + // to make sure any exceptions are caught and logged. + ignorePromiseRejections(postMessageSendPromise); } await Promise.all([ diff --git a/keyserver/src/creators/report-creator.js b/keyserver/src/creators/report-creator.js --- a/keyserver/src/creators/report-creator.js +++ b/keyserver/src/creators/report-creator.js @@ -17,6 +17,7 @@ reportTypes, } from 'lib/types/report-types.js'; import { values } from 'lib/utils/objects.js'; +import { ignorePromiseRejections } from 'lib/utils/promises.js'; import { sanitizeReduxReport, type ReduxCrashReport, @@ -26,7 +27,6 @@ import createMessages from './message-creator.js'; import { dbQuery, SQL } from '../database/database.js'; import { fetchUsername } from '../fetchers/user-fetchers.js'; -import { handleAsyncPromise } from '../responders/handlers.js'; import { createBotViewer } from '../session/bots.js'; import type { Viewer } from '../session/viewer.js'; import { getAndAssertKeyserverURLFacts } from '../utils/urls.js'; @@ -78,7 +78,7 @@ VALUES ${[row]} `; await dbQuery(query); - handleAsyncPromise(sendCommbotMessage(viewer, request, id)); + ignorePromiseRejections(sendCommbotMessage(viewer, request, id)); return { id }; } diff --git a/keyserver/src/cron/update-geoip-db.js b/keyserver/src/cron/update-geoip-db.js --- a/keyserver/src/cron/update-geoip-db.js +++ b/keyserver/src/cron/update-geoip-db.js @@ -5,8 +5,7 @@ import geoip from 'geoip-lite'; import { getCommConfig } from 'lib/utils/comm-config.js'; - -import { handleAsyncPromise } from '../responders/handlers.js'; +import { ignorePromiseRejections } from 'lib/utils/promises.js'; type GeoIPLicenseConfig = { +key: string }; async function updateGeoipDB(): Promise { @@ -56,7 +55,7 @@ if (!cluster.isMaster) { process.on('message', (ipcMessage: IPCMessage) => { if (ipcMessage.type === 'geoip_reload') { - handleAsyncPromise(reloadGeoipDB()); + ignorePromiseRejections(reloadGeoipDB()); } }); } diff --git a/keyserver/src/deleters/account-deleters.js b/keyserver/src/deleters/account-deleters.js --- a/keyserver/src/deleters/account-deleters.js +++ b/keyserver/src/deleters/account-deleters.js @@ -8,7 +8,7 @@ import type { UserInfo } from 'lib/types/user-types.js'; import { ServerError } from 'lib/utils/errors.js'; import { values } from 'lib/utils/objects.js'; -import { promiseAll } from 'lib/utils/promises.js'; +import { promiseAll, ignorePromiseRejections } from 'lib/utils/promises.js'; import { createUpdates } from '../creators/update-creator.js'; import { dbQuery, SQL } from '../database/database.js'; @@ -17,7 +17,6 @@ fetchUsername, } from '../fetchers/user-fetchers.js'; import { rescindPushNotifs } from '../push/rescind.js'; -import { handleAsyncPromise } from '../responders/handlers.js'; import { createNewAnonymousCookie } from '../session/cookies.js'; import type { Viewer, AnonymousViewerData } from '../session/viewer.js'; import { fetchOlmAccount } from '../updaters/olm-account-updater.js'; @@ -98,7 +97,7 @@ }; const message = JSON.stringify(reservedUsernameMessage); - handleAsyncPromise( + ignorePromiseRejections( (async () => { const rustAPI = await getRustAPI(); const accountInfo = await fetchOlmAccount('content'); @@ -119,7 +118,7 @@ if (viewer.isScriptViewer) { await deletionUpdatesPromise; } else { - handleAsyncPromise(deletionUpdatesPromise); + ignorePromiseRejections(deletionUpdatesPromise); } if (viewer.isScriptViewer) { diff --git a/keyserver/src/keyserver.js b/keyserver/src/keyserver.js --- a/keyserver/src/keyserver.js +++ b/keyserver/src/keyserver.js @@ -15,6 +15,7 @@ import './cron/cron.js'; import { qrCodeLinkURL } from 'lib/facts/links.js'; import { isDev } from 'lib/utils/dev-utils.js'; +import { ignorePromiseRejections } from 'lib/utils/promises.js'; import { migrate } from './database/migrations.js'; import { jsonEndpoints } from './endpoints.js'; @@ -23,7 +24,6 @@ import { jsonHandler, downloadHandler, - handleAsyncPromise, htmlHandler, uploadHandler, } from './responders/handlers.js'; @@ -103,7 +103,9 @@ // We don't await here, as Tunnelbroker communication is not needed for // normal keyserver behavior yet. In addition, this doesn't return // information useful for other keyserver functions. - handleAsyncPromise(createAndMaintainTunnelbrokerWebsocket(identityInfo)); + ignorePromiseRejections( + createAndMaintainTunnelbrokerWebsocket(identityInfo), + ); } catch (e) { console.warn( 'Failed identity login. Login optional until staging environment is available', diff --git a/keyserver/src/responders/handlers.js b/keyserver/src/responders/handlers.js --- a/keyserver/src/responders/handlers.js +++ b/keyserver/src/responders/handlers.js @@ -227,14 +227,6 @@ }; } -async function handleAsyncPromise(promise: Promise) { - try { - await promise; - } catch (error) { - console.warn(error); - } -} - export { createJSONResponder, jsonHandler, @@ -242,5 +234,4 @@ downloadHandler, htmlHandler, uploadHandler, - handleAsyncPromise, }; diff --git a/keyserver/src/session/cookies.js b/keyserver/src/session/cookies.js --- a/keyserver/src/session/cookies.js +++ b/keyserver/src/session/cookies.js @@ -21,6 +21,7 @@ import type { InitialClientSocketMessage } from 'lib/types/socket-types.js'; import type { UserInfo } from 'lib/types/user-types.js'; import { isDev } from 'lib/utils/dev-utils.js'; +import { ignorePromiseRejections } from 'lib/utils/promises.js'; import { isBcryptHash, @@ -33,7 +34,6 @@ import { createSession } from '../creators/session-creator.js'; import { dbQuery, SQL } from '../database/database.js'; import { deleteCookie } from '../deleters/cookie-deleters.js'; -import { handleAsyncPromise } from '../responders/handlers.js'; import { clearDeviceToken } from '../updaters/device-token-updaters.js'; import { assertSecureRequest } from '../utils/security-utils.js'; import { @@ -676,7 +676,7 @@ viewer.cookieInvalidated = false; } if (!viewer.getData().cookieInsertedThisRequest) { - handleAsyncPromise(updateCookie(viewer)); + ignorePromiseRejections(updateCookie(viewer)); } if (viewer.sessionChanged) { addSessionChangeInfoToResult(viewer, res, result); diff --git a/keyserver/src/socket/session-utils.js b/keyserver/src/socket/session-utils.js --- a/keyserver/src/socket/session-utils.js +++ b/keyserver/src/socket/session-utils.js @@ -31,7 +31,7 @@ import { sessionCheckFrequency } from 'lib/types/session-types.js'; import { signedIdentityKeysBlobValidator } from 'lib/utils/crypto-utils.js'; import { hash, values } from 'lib/utils/objects.js'; -import { promiseAll } from 'lib/utils/promises.js'; +import { promiseAll, ignorePromiseRejections } from 'lib/utils/promises.js'; import { tShape, tPlatform, @@ -44,7 +44,6 @@ import { fetchEntriesForSession } from '../fetchers/entry-fetchers.js'; import { checkIfSessionHasEnoughOneTimeKeys } from '../fetchers/key-fetchers.js'; import { activityUpdatesInputValidator } from '../responders/activity-responders.js'; -import { handleAsyncPromise } from '../responders/handlers.js'; import { threadInconsistencyReportValidatorShape, entryInconsistencyReportValidatorShape, @@ -197,7 +196,7 @@ : { status: 'state_validated' }; } else if (clientResponse.type === serverRequestTypes.MORE_ONE_TIME_KEYS) { invariant(clientResponse.keys, 'keys expected in client response'); - handleAsyncPromise(saveOneTimeKeys(viewer, clientResponse.keys)); + ignorePromiseRejections(saveOneTimeKeys(viewer, clientResponse.keys)); } else if ( clientResponse.type === serverRequestTypes.SIGNED_IDENTITY_KEYS_BLOB ) { @@ -216,7 +215,7 @@ signedIdentityKeysBlob.payload, signedIdentityKeysBlob.signature, ); - handleAsyncPromise( + ignorePromiseRejections( setCookieSignedIdentityKeysBlob( viewer.cookieID, signedIdentityKeysBlob, diff --git a/keyserver/src/socket/socket.js b/keyserver/src/socket/socket.js --- a/keyserver/src/socket/socket.js +++ b/keyserver/src/socket/socket.js @@ -45,7 +45,7 @@ import type { UserInfo, CurrentUserInfo } from 'lib/types/user-types.js'; import { ServerError } from 'lib/utils/errors.js'; import { values } from 'lib/utils/objects.js'; -import { promiseAll } from 'lib/utils/promises.js'; +import { promiseAll, ignorePromiseRejections } from 'lib/utils/promises.js'; import SequentialPromiseResolver from 'lib/utils/sequential-promise-resolver.js'; import sleep from 'lib/utils/sleep.js'; import { tShape, tCookie } from 'lib/utils/validation-utils.js'; @@ -71,7 +71,6 @@ newEntryQueryInputValidator, verifyCalendarQueryThreadIDs, } from '../responders/entry-responders.js'; -import { handleAsyncPromise } from '../responders/handlers.js'; import { fetchViewerForSocket, updateCookie, @@ -250,7 +249,7 @@ throw new ServerError('session_mutated_from_socket'); } if (clientSocketMessage.type !== clientSocketMessageTypes.PING) { - handleAsyncPromise(updateCookie(viewer)); + ignorePromiseRejections(updateCookie(viewer)); } for (const response of serverResponses) { // Normally it's an anti-pattern to await in sequence like this. But in diff --git a/keyserver/src/updaters/thread-updaters.js b/keyserver/src/updaters/thread-updaters.js --- a/keyserver/src/updaters/thread-updaters.js +++ b/keyserver/src/updaters/thread-updaters.js @@ -28,7 +28,7 @@ } from 'lib/types/thread-types.js'; import { updateTypes } from 'lib/types/update-types-enum.js'; import { ServerError } from 'lib/utils/errors.js'; -import { promiseAll } from 'lib/utils/promises.js'; +import { promiseAll, ignorePromiseRejections } from 'lib/utils/promises.js'; import { firstLine } from 'lib/utils/string-utils.js'; import { canToggleMessagePin } from 'lib/utils/toggle-pin-utils.js'; import { validChatNameRegex } from 'lib/utils/validation-utils.js'; @@ -63,7 +63,6 @@ verifyUserIDs, verifyUserOrCookieIDs, } from '../fetchers/user-fetchers.js'; -import { handleAsyncPromise } from '../responders/handlers.js'; import type { Viewer } from '../session/viewer.js'; import RelationshipChangeset from '../utils/relationship-changeset.js'; @@ -861,7 +860,7 @@ }); if (request.inviteLinkSecret) { - handleAsyncPromise(reportLinkUsage(request.inviteLinkSecret)); + ignorePromiseRejections(reportLinkUsage(request.inviteLinkSecret)); } const messageData = { diff --git a/lib/utils/promises.js b/lib/utils/promises.js --- a/lib/utils/promises.js +++ b/lib/utils/promises.js @@ -29,4 +29,12 @@ return input.filter((value, index) => filterResults[index]); } -export { promiseAll, promiseFilter }; +async function ignorePromiseRejections(promise: Promise) { + try { + await promise; + } catch (error) { + console.warn(error); + } +} + +export { promiseAll, promiseFilter, ignorePromiseRejections };