|
3 | 3 | const { redis } = require('./db'); |
4 | 4 | const msgpack = require('msgpack5')(); |
5 | 5 | const logger = require('./logger'); |
6 | | -const { REDIS_PREFIX } = require('./consts'); |
| 6 | +const { REDIS_PREFIX, TRANSIENT_NETWORK_CODES } = require('./consts'); |
7 | 7 | const { encrypt, decrypt } = require('./encrypt'); |
8 | 8 | const Boom = require('@hapi/boom'); |
9 | 9 | const settings = require('./settings'); |
10 | 10 | const Lock = require('ioredfour'); |
11 | 11 | const getSecret = require('./get-secret'); |
12 | 12 | const { parentPort } = require('worker_threads'); |
13 | 13 |
|
14 | | -const TRANSIENT_NETWORK_CODES = new Set([ |
15 | | - 'ENOTFOUND', |
16 | | - 'EAI_AGAIN', |
17 | | - 'ETIMEDOUT', |
18 | | - 'ECONNRESET', |
19 | | - 'ECONNREFUSED', |
20 | | - 'UND_ERR_SOCKET', |
21 | | - 'UND_ERR_CONNECT_TIMEOUT', |
22 | | - 'UND_ERR_HEADERS_TIMEOUT' |
23 | | -]); |
24 | | - |
25 | 14 | /** |
26 | 15 | * Record metrics for OAuth2 token operations |
27 | 16 | * Works in both main thread and worker threads |
@@ -706,17 +695,7 @@ class OAuth2AppsHandler { |
706 | 695 | created: true |
707 | 696 | }; |
708 | 697 |
|
709 | | - try { |
710 | | - let appData = await this.get(id); |
711 | | - if (appData.baseScopes === 'pubsub') { |
712 | | - let pubsubUpdates = await this.ensurePubsub(appData); |
713 | | - if (Object.keys(pubsubUpdates || {}).length) { |
714 | | - result.pubsubUpdates = pubsubUpdates; |
715 | | - } |
716 | | - } |
717 | | - } catch (err) { |
718 | | - logger.error({ msg: 'Failed to set up pubsub', app: id, err }); |
719 | | - } |
| 698 | + await this.tryEnsurePubsub(id, result); |
720 | 699 |
|
721 | 700 | return result; |
722 | 701 | } |
@@ -790,17 +769,7 @@ class OAuth2AppsHandler { |
790 | 769 | updated: true |
791 | 770 | }; |
792 | 771 |
|
793 | | - try { |
794 | | - let appData = await this.get(id); |
795 | | - if (appData.baseScopes === 'pubsub') { |
796 | | - let pubsubUpdates = await this.ensurePubsub(appData); |
797 | | - if (Object.keys(pubsubUpdates || {}).length) { |
798 | | - result.pubsubUpdates = pubsubUpdates; |
799 | | - } |
800 | | - } |
801 | | - } catch (err) { |
802 | | - logger.error({ msg: 'Failed to set up pubsub', app: id, err }); |
803 | | - } |
| 772 | + await this.tryEnsurePubsub(id, result); |
804 | 773 |
|
805 | 774 | return result; |
806 | 775 | } |
@@ -876,6 +845,35 @@ class OAuth2AppsHandler { |
876 | 845 | }; |
877 | 846 | } |
878 | 847 |
|
| 848 | + /** |
| 849 | + * Fire-and-forget setMeta call that logs errors instead of throwing. |
| 850 | + * Used in ensurePubsub error handlers where we want to record a flag |
| 851 | + * but must not block or alter the original error flow. |
| 852 | + */ |
| 853 | + setMetaFireAndForget(appId, meta) { |
| 854 | + this.setMeta(appId, meta).catch(metaErr => { |
| 855 | + logger.error({ msg: 'Failed to set metadata', app: appId, err: metaErr }); |
| 856 | + }); |
| 857 | + } |
| 858 | + |
| 859 | + /** |
| 860 | + * Try to set up Pub/Sub for the given app and attach results to the result object. |
| 861 | + * Errors are logged but not thrown so they do not prevent create/update from succeeding. |
| 862 | + */ |
| 863 | + async tryEnsurePubsub(id, result) { |
| 864 | + try { |
| 865 | + let appData = await this.get(id); |
| 866 | + if (appData.baseScopes === 'pubsub') { |
| 867 | + let pubsubUpdates = await this.ensurePubsub(appData); |
| 868 | + if (Object.keys(pubsubUpdates || {}).length) { |
| 869 | + result.pubsubUpdates = pubsubUpdates; |
| 870 | + } |
| 871 | + } |
| 872 | + } catch (err) { |
| 873 | + logger.error({ msg: 'Failed to set up pubsub', app: id, err }); |
| 874 | + } |
| 875 | + } |
| 876 | + |
879 | 877 | async deleteTopic(appData) { |
880 | 878 | let topicName = appData.pubSubTopic; |
881 | 879 | let topicUrl = `https://pubsub.googleapis.com/v1/${topicName}`; |
@@ -1008,22 +1006,18 @@ class OAuth2AppsHandler { |
1008 | 1006 | case 403: |
1009 | 1007 | // no permissions |
1010 | 1008 | if (/Cloud Pub\/Sub API has not been used in project/.test(err?.oauthRequest?.response?.error?.message)) { |
1011 | | - this.setMeta(appData.id, { |
| 1009 | + this.setMetaFireAndForget(appData.id, { |
1012 | 1010 | authFlag: { |
1013 | 1011 | message: |
1014 | 1012 | 'Enable the Cloud Pub/Sub API for your project before using the service client. Check the server response below for details.', |
1015 | 1013 | description: err?.oauthRequest?.response?.error?.message |
1016 | 1014 | } |
1017 | | - }).catch(metaErr => { |
1018 | | - logger.error({ msg: 'Failed to set authFlag metadata', app: appData.id, err: metaErr }); |
1019 | 1015 | }); |
1020 | 1016 | } else { |
1021 | | - this.setMeta(appData.id, { |
| 1017 | + this.setMetaFireAndForget(appData.id, { |
1022 | 1018 | authFlag: { |
1023 | 1019 | message: 'Service client does not have permission to manage Pub/Sub topics. Grant the service user the "Pub/Sub Admin" role.' |
1024 | 1020 | } |
1025 | | - }).catch(metaErr => { |
1026 | | - logger.error({ msg: 'Failed to set authFlag metadata', app: appData.id, err: metaErr }); |
1027 | 1021 | }); |
1028 | 1022 | } |
1029 | 1023 |
|
@@ -1057,13 +1051,11 @@ class OAuth2AppsHandler { |
1057 | 1051 | switch (err?.oauthRequest?.response?.error?.code) { |
1058 | 1052 | case 403: |
1059 | 1053 | // no permissions |
1060 | | - this.setMeta(appData.id, { |
| 1054 | + this.setMetaFireAndForget(appData.id, { |
1061 | 1055 | authFlag: { |
1062 | 1056 | message: |
1063 | 1057 | 'Service client does not have permission to manage Pub/Sub topics. Grant the service user the "Pub/Sub Admin" role.' |
1064 | 1058 | } |
1065 | | - }).catch(metaErr => { |
1066 | | - logger.error({ msg: 'Failed to set authFlag metadata', app: appData.id, err: metaErr }); |
1067 | 1059 | }); |
1068 | 1060 | throw err; |
1069 | 1061 | case 409: |
@@ -1132,12 +1124,10 @@ class OAuth2AppsHandler { |
1132 | 1124 | switch (err?.oauthRequest?.response?.error?.code) { |
1133 | 1125 | case 403: |
1134 | 1126 | // no permissions |
1135 | | - this.setMeta(appData.id, { |
| 1127 | + this.setMetaFireAndForget(appData.id, { |
1136 | 1128 | authFlag: { |
1137 | 1129 | message: 'Service client does not have permission to view Pub/Sub topics. Grant the service user the "Pub/Sub Admin" role.' |
1138 | 1130 | } |
1139 | | - }).catch(metaErr => { |
1140 | | - logger.error({ msg: 'Failed to set authFlag metadata', app: appData.id, err: metaErr }); |
1141 | 1131 | }); |
1142 | 1132 | throw err; |
1143 | 1133 | case 404: { |
@@ -1190,13 +1180,11 @@ class OAuth2AppsHandler { |
1190 | 1180 | switch (err?.oauthRequest?.response?.error?.code) { |
1191 | 1181 | case 403: |
1192 | 1182 | // no permissions |
1193 | | - this.setMeta(appData.id, { |
| 1183 | + this.setMetaFireAndForget(appData.id, { |
1194 | 1184 | authFlag: { |
1195 | 1185 | message: |
1196 | 1186 | 'Service client does not have permission to manage Pub/Sub topics. Grant the service user the "Pub/Sub Admin" role.' |
1197 | 1187 | } |
1198 | | - }).catch(metaErr => { |
1199 | | - logger.error({ msg: 'Failed to set authFlag metadata', app: appData.id, err: metaErr }); |
1200 | 1188 | }); |
1201 | 1189 | throw err; |
1202 | 1190 | case 409: |
@@ -1241,12 +1229,10 @@ class OAuth2AppsHandler { |
1241 | 1229 | switch (err?.oauthRequest?.response?.error?.code) { |
1242 | 1230 | case 403: |
1243 | 1231 | // no permissions |
1244 | | - this.setMeta(appData.id, { |
| 1232 | + this.setMetaFireAndForget(appData.id, { |
1245 | 1233 | authFlag: { |
1246 | 1234 | message: 'Service client does not have permission to view Pub/Sub topics. Grant the service user the "Pub/Sub Admin" role.' |
1247 | 1235 | } |
1248 | | - }).catch(metaErr => { |
1249 | | - logger.error({ msg: 'Failed to set authFlag metadata', app: appData.id, err: metaErr }); |
1250 | 1236 | }); |
1251 | 1237 | throw err; |
1252 | 1238 | default: |
@@ -1290,12 +1276,10 @@ class OAuth2AppsHandler { |
1290 | 1276 | switch (err?.oauthRequest?.response?.error?.code) { |
1291 | 1277 | case 403: |
1292 | 1278 | // no permissions |
1293 | | - this.setMeta(appData.id, { |
| 1279 | + this.setMetaFireAndForget(appData.id, { |
1294 | 1280 | authFlag: { |
1295 | 1281 | message: 'Service client does not have permission to manage Pub/Sub topics. Grant the service user the "Pub/Sub Admin" role.' |
1296 | 1282 | } |
1297 | | - }).catch(metaErr => { |
1298 | | - logger.error({ msg: 'Failed to set authFlag metadata', app: appData.id, err: metaErr }); |
1299 | 1283 | }); |
1300 | 1284 | throw err; |
1301 | 1285 | default: |
|
0 commit comments