Просмотр исходного кода

Handle errors when processing command line arguments

GitOrigin-RevId: 7c1f011e705d6e4b6fbf0afee3dc3aab749f0de4
Andrew Rumble 1 год назад
Родитель
Сommit
797f29d40a
1 измененных файлов с 64 добавлено и 19 удалено
  1. 64 19
      services/history-v1/storage/scripts/recover_zip_from_backup.mjs

+ 64 - 19
services/history-v1/storage/scripts/recover_zip_from_backup.mjs

@@ -31,6 +31,16 @@ async function shutdown(code = 0) {
   process.exit(code)
 }
 
+function usage() {
+  console.log(
+    'Usage: node recover_zip_from_backup.mjs --historyId=<historyId> --output=<output> [--mode=<mode>] [--verbose] [--useBackupGlobalBlobs]'
+  )
+  console.log('Supported modes: ' + SUPPORTED_MODES.join(', '))
+  console.log(
+    '--useBackupGlobalBlobs can be used if the global blobs have not been restored from the backup yet.'
+  )
+}
+
 /**
  * @typedef {import('archiver').ZipArchive} ZipArchive
  */
@@ -50,21 +60,37 @@ async function shutdown(code = 0) {
  * @property {Object} data
  */
 
-const { historyId, mode, output, verbose } = commandLineArgs([
-  { name: 'historyId', type: String },
-  { name: 'output', type: String },
-  { name: 'mode', type: String, defaultValue: 'raw' },
-  { name: 'verbose', type: String, defaultValue: false },
-])
+let historyId, help, mode, output, useBackupGlobalBlobs, verbose
+
+try {
+  ;({ historyId, help, mode, output, useBackupGlobalBlobs, verbose } =
+    commandLineArgs([
+      { name: 'historyId', type: String },
+      { name: 'output', type: String },
+      { name: 'mode', type: String, defaultValue: 'raw' },
+      { name: 'verbose', type: Boolean, defaultValue: false },
+      { name: 'useBackupGlobalBlobs', type: Boolean, defaultValue: false },
+      { name: 'help', type: Boolean },
+    ]))
+} catch (err) {
+  console.error(err.message)
+  help = true
+}
+
+if (help) {
+  usage()
+  await shutdown(0)
+}
 
 if (!historyId) {
   console.error('missing --historyId')
+  usage()
   await shutdown(1)
 }
 
 if (!output) {
   console.error('missing --output')
-
+  usage()
   await shutdown(1)
 }
 
@@ -147,16 +173,35 @@ archive.on(
   }
 )
 
-switch (mode) {
-  case 'latest':
-    await archiveLatestChunk(archive, historyId)
-    break
-  case 'raw':
-  default:
-    await archiveRawProject(archive, historyId)
-    break
+try {
+  switch (mode) {
+    case 'latest':
+      await archiveLatestChunk(archive, historyId, useBackupGlobalBlobs)
+      break
+    case 'raw':
+    default:
+      await archiveRawProject(archive, historyId, useBackupGlobalBlobs)
+      break
+  }
+  archive.pipe(outputFile)
+} catch (error) {
+  if (error instanceof BackupPersistorError) {
+    console.error(error.message)
+  }
+  if (error instanceof Chunk.NotPersistedError) {
+    console.error('Chunk not found. Project may not have been fully backed up.')
+  }
+  if (verbose) {
+    console.error(error)
+  } else {
+    console.error('Error encountered when writing archive')
+  }
+} finally {
+  await Promise.race([
+    await archive.finalize(),
+    setTimeout(10000).then(() => {
+      console.error('Archive did not finalize in time')
+      return shutdown(1)
+    }),
+  ])
 }
-
-archive.pipe(outputFile)
-
-await archive.finalize()