Ejemplo n.º 1
0
        public async Task TestFailedConversionsMissingAsset()
        {
            var client = GetClient();

            Uri storageUri = new Uri($"https://{TestEnvironment.StorageAccountName}.blob.core.windows.net/{TestEnvironment.BlobContainerName}");

            AssetConversionInputOptions input = new AssetConversionInputOptions(storageUri, "boxWhichDoesNotExist.fbx")
            {
                // We use SAS for live testing, as there can be a delay before DRAM-based access is available for new accounts.
                StorageContainerReadListSas = TestEnvironment.SasToken,
                BlobPrefix = "Input"
            };
            AssetConversionOutputOptions output = new AssetConversionOutputOptions(storageUri)
            {
                StorageContainerWriteSas = TestEnvironment.SasToken,
                BlobPrefix = "Output"
            };
            AssetConversionOptions conversionOptions = new AssetConversionOptions(input, output);

            string conversionId = Recording.Random.NewGuid().ToString();

            AssetConversionOperation conversionOperation = await client.StartConversionAsync(conversionId, conversionOptions);

            AssetConversion conversion = await conversionOperation.WaitForCompletionAsync();

            Assert.AreEqual(AssetConversionStatus.Failed, conversion.Status);
            Assert.IsNotNull(conversion.Error);
            // Invalid input provided. Check logs in output container for details.
            Assert.IsTrue(conversion.Error.Message.ToLower().Contains("invalid input"));
            Assert.IsTrue(conversion.Error.Message.ToLower().Contains("logs"));
        }
Ejemplo n.º 2
0
        public void ConvertSimpleAsset()
        {
            RemoteRenderingClient client = GetClient();

            Uri storageUri = new Uri($"https://{TestEnvironment.StorageAccountName}.blob.core.windows.net/{TestEnvironment.BlobContainerName}");

            #region Snippet:StartAnAssetConversion

            AssetConversionInputOptions  inputOptions      = new AssetConversionInputOptions(storageUri, "box.fbx");
            AssetConversionOutputOptions outputOptions     = new AssetConversionOutputOptions(storageUri);
            AssetConversionOptions       conversionOptions = new AssetConversionOptions(inputOptions, outputOptions);

            // A randomly generated GUID is a good choice for a conversionId.
            string conversionId = Guid.NewGuid().ToString();

            AssetConversionOperation conversionOperation = client.StartConversion(conversionId, conversionOptions);

            #endregion Snippet:StartAnAssetConversion
            #region Snippet:QueryAssetConversion

            AssetConversion conversion = conversionOperation.WaitForCompletionAsync().Result;
            if (conversion.Status == AssetConversionStatus.Succeeded)
            {
                Console.WriteLine($"Conversion succeeded: Output written to {conversion.Output.OutputAssetUri}");
            }
            else if (conversion.Status == AssetConversionStatus.Failed)
            {
                Console.WriteLine($"Conversion failed: {conversion.Error.Code} {conversion.Error.Message}");
            }

            #endregion Snippet:QueryAssetConversion
        }
        public async Task ObserveExistingAssetConversion()
        {
            (
                ObjectAnchorsConversionClient clientWithWorkingInternalMethods,
                ObjectAnchorsConversionClient client,
                AssetConversionOptions assetConversionOptions
            ) = await GetClientsAndConversionOptionsForAsset(assetLocalFilePath);

            Guid jobId = new Guid((await client.StartAssetConversionAsync(assetConversionOptions)).Id);

            AssetConversionOperation operation = InstrumentOperation(new AssetConversionOperation(jobId, clientWithWorkingInternalMethods));

            await operation.WaitForCompletionAsync();

            if (!operation.HasCompletedSuccessfully)
            {
                throw new Exception("The asset conversion operation completed with an unsuccessful status");
            }

            string localFileDownloadPath = modelDownloadLocalFilePath;

            BlobClient downloadBlobClient = InstrumentClient(new BlobClient(operation.Value.OutputModelUri, InstrumentClientOptions(new BlobClientOptions(BlobClientOptions.ServiceVersion.V2019_12_12))));

            BlobDownloadInfo downloadInfo = await downloadBlobClient.DownloadAsync();

            using (FileStream file = File.OpenWrite(localFileDownloadPath))
            {
                await downloadInfo.Content.CopyToAsync(file);

                var fileInfo = new FileInfo(localFileDownloadPath);
                Assert.Greater(fileInfo.Length, 0);
            }
        }
Ejemplo n.º 4
0
        public void ConvertMoreComplexAsset()
        {
            RemoteRenderingClient client = GetClient();

            Uri inputStorageUri  = new Uri($"https://{TestEnvironment.StorageAccountName}.blob.core.windows.net/{TestEnvironment.BlobContainerName}");
            Uri outputStorageUri = new Uri($"https://{TestEnvironment.StorageAccountName}.blob.core.windows.net/{TestEnvironment.BlobContainerName}");

            #region Snippet:StartAComplexAssetConversion
            AssetConversionInputOptions inputOptions = new AssetConversionInputOptions(inputStorageUri, "bicycle.gltf")
            {
                BlobPrefix = "Bicycle"
            };
            AssetConversionOutputOptions outputOptions = new AssetConversionOutputOptions(outputStorageUri)
            {
                BlobPrefix = "ConvertedBicycle"
            };
            AssetConversionOptions conversionOptions = new AssetConversionOptions(inputOptions, outputOptions);

            string conversionId = Guid.NewGuid().ToString();

            AssetConversionOperation conversionOperation = client.StartConversion(conversionId, conversionOptions);
            #endregion Snippet:StartAComplexAssetConversion

            AssetConversion conversion = conversionOperation.WaitForCompletionAsync().Result;
            if (conversion.Status == AssetConversionStatus.Succeeded)
            {
                Console.WriteLine($"Conversion succeeded: Output written to {conversion.Output.OutputAssetUri}");
            }
            else if (conversion.Status == AssetConversionStatus.Failed)
            {
                Console.WriteLine($"Conversion failed: {conversion.Error.Code} {conversion.Error.Message}");
            }
        }
        public async Task <Guid> StartAssetConversion()
        {
            Guid    accountId     = new Guid(TestEnvironment.AccountId);
            string  accountDomain = TestEnvironment.AccountDomain;
            string  localFilePath = assetLocalFilePath;
            Vector3 assetGravity  = new Vector3(assetGravityX, assetGravityY, assetGravityZ);
            float   scale         = assetScale;

            AzureKeyCredential credential = new AzureKeyCredential(TestEnvironment.AccountKey);

            ObjectAnchorsConversionClient client = new ObjectAnchorsConversionClient(accountId, accountDomain, credential);

            Uri uploadedInputAssetUri = (await client.GetAssetUploadUriAsync()).Value.UploadUri;

            BlobClient uploadBlobClient = new BlobClient(uploadedInputAssetUri, new BlobClientOptions());

            using (FileStream fs = File.OpenRead(localFilePath))
            {
                await uploadBlobClient.UploadAsync(fs);
            }

            AssetConversionOptions ingestionJobOptions = new AssetConversionOptions(uploadedInputAssetUri, AssetFileType.FromFilePath(localFilePath), assetGravity, scale);

            AssetConversionOperation operation = await client.StartAssetConversionAsync(ingestionJobOptions);

            return(new Guid(operation.Id));
        }
Ejemplo n.º 6
0
        public async Task <FileInfo> DownloadConvertedAsset(Guid jobId)
        {
            Guid                          accountId     = new Guid(TestEnvironment.AccountId);
            string                        accountDomain = TestEnvironment.AccountDomain;
            AzureKeyCredential            credential    = new AzureKeyCredential(TestEnvironment.AccountKey);
            ObjectAnchorsConversionClient client        = new ObjectAnchorsConversionClient(accountId, accountDomain, credential);

            AssetConversionOperation operation = new AssetConversionOperation(jobId, client);

            await operation.WaitForCompletionAsync();

            if (!operation.HasCompletedSuccessfully)
            {
                throw new Exception("The asset conversion operation completed with an unsuccessful status");
            }

            string localFileDownloadPath = modelDownloadLocalFilePath;

            BlobClient downloadBlobClient = new BlobClient(operation.Value.OutputModelUri, new BlobClientOptions());

            BlobDownloadInfo downloadInfo = await downloadBlobClient.DownloadAsync();

            using (FileStream file = File.OpenWrite(localFileDownloadPath))
            {
                await downloadInfo.Content.CopyToAsync(file);

                return(new FileInfo(localFileDownloadPath));
            }
        }
        public async Task ObserveExistingAssetConversion()
        {
            Recording.DisableIdReuse();

            string  localFilePath = assetLocalFilePath;
            Vector3 assetGravity  = new Vector3(assetGravityX, assetGravityY, assetGravityZ);
            float   scale         = assetScale;

            var clientWithWorkingInternalMethods = CreateClient();
            ObjectAnchorsConversionClient client = InstrumentClient(clientWithWorkingInternalMethods);

            AssetUploadUriResult uploadUriResult = await client.GetAssetUploadUriAsync();

            Uri uploadedInputAssetUri = uploadUriResult.UploadUri;

            BlobClient uploadBlobClient = InstrumentClient(new BlobClient(uploadedInputAssetUri, InstrumentClientOptions(new BlobClientOptions(BlobClientOptions.ServiceVersion.V2019_12_12))));

            using (FileStream fs = File.OpenRead(localFilePath))
            {
                await uploadBlobClient.UploadAsync(fs);
            }

            AssetConversionOptions assetConversionOptions = new AssetConversionOptions(uploadedInputAssetUri, AssetFileType.FromFilePath(localFilePath), assetGravity, scale);

            assetConversionOptions.JobId = Recording.Random.NewGuid();

            Guid jobId = new Guid((await client.StartAssetConversionAsync(assetConversionOptions)).Id);

            AssetConversionOperation operation = new AssetConversionOperation(jobId, clientWithWorkingInternalMethods);

            await operation.WaitForCompletionAsync();

            if (!operation.HasCompletedSuccessfully)
            {
                throw new Exception("The asset conversion operation completed with an unsuccessful status");
            }

            string localFileDownloadPath = modelDownloadLocalFilePath;

            BlobClient downloadBlobClient = InstrumentClient(new BlobClient(operation.Value.OutputModelUri, InstrumentClientOptions(new BlobClientOptions(BlobClientOptions.ServiceVersion.V2019_12_12))));

            BlobDownloadInfo downloadInfo = await downloadBlobClient.DownloadAsync();

            using (FileStream file = File.OpenWrite(localFileDownloadPath))
            {
                await downloadInfo.Content.CopyToAsync(file);

                var fileInfo = new FileInfo(localFileDownloadPath);
                Assert.Greater(fileInfo.Length, 0);
            }
        }
Ejemplo n.º 8
0
        public async Task TestSimpleConversion()
        {
            var client = GetClient();

            Uri storageUri = new Uri($"https://{TestEnvironment.StorageAccountName}.blob.core.windows.net/{TestEnvironment.BlobContainerName}");

            AssetConversionInputOptions input = new AssetConversionInputOptions(storageUri, "testBox.fbx")
            {
                // We use SAS for live testing, as there can be a delay before DRAM-based access is available for new accounts.
                StorageContainerReadListSas = TestEnvironment.SasToken,
                BlobPrefix = "Input"
            };
            AssetConversionOutputOptions output = new AssetConversionOutputOptions(storageUri)
            {
                StorageContainerWriteSas = TestEnvironment.SasToken,
                BlobPrefix = "Output"
            };
            AssetConversionOptions conversionOptions = new AssetConversionOptions(input, output);

            string conversionId = Recording.Random.NewGuid().ToString();

            AssetConversionOperation conversionOperation = await client.StartConversionAsync(conversionId, conversionOptions);

            Assert.AreEqual(conversionId, conversionOperation.Id);
            Assert.AreEqual(conversionOptions.InputOptions.RelativeInputAssetPath, conversionOperation.Value.Options.InputOptions.RelativeInputAssetPath);
            Assert.AreNotEqual(AssetConversionStatus.Failed, conversionOperation.Value.Status);

            AssetConversion conversion = await client.GetConversionAsync(conversionId);

            Assert.AreEqual(conversion.ConversionId, conversionId);
            Assert.AreNotEqual(AssetConversionStatus.Failed, conversion.Status);

            AssetConversion conversion2 = await conversionOperation.WaitForCompletionAsync();

            Assert.AreEqual(conversionId, conversion2.ConversionId);
            Assert.AreEqual(AssetConversionStatus.Succeeded, conversion2.Status);
            Assert.IsTrue(conversionOperation.Value.Output.OutputAssetUri.EndsWith("Output/testBox.arrAsset"));

            bool foundConversion = false;

            await foreach (var s in client.GetConversionsAync())
            {
                if (s.ConversionId == conversionId)
                {
                    foundConversion = true;
                }
            }
            Assert.IsTrue(foundConversion);
        }
        public async Task WaitForAssetConversionToComplete(Guid jobId)
        {
            Guid                          accountId     = new Guid(TestEnvironment.AccountId);
            string                        accountDomain = TestEnvironment.AccountDomain;
            AzureKeyCredential            credential    = new AzureKeyCredential(TestEnvironment.AccountKey);
            ObjectAnchorsConversionClient client        = new ObjectAnchorsConversionClient(accountId, accountDomain, credential);

            AssetConversionOperation operation = new AssetConversionOperation(jobId, client);

            await operation.WaitForCompletionAsync();

            if (!operation.HasCompletedSuccessfully)
            {
                throw new Exception("The asset conversion operation completed with an unsuccessful status");
            }
        }
        public async Task RunFailedAssetConversion()
        {
            (
                ObjectAnchorsConversionClient clientWithWorkingInternalMethods,
                ObjectAnchorsConversionClient client,
                AssetConversionOptions assetConversionOptions
            ) = await GetClientsAndConversionOptionsForAsset(fakeAssetLocalFilePath);

            AssetConversionOperation operation = await client.StartAssetConversionAsync(assetConversionOptions);

            await operation.WaitForCompletionAsync();

            if (operation.HasCompletedSuccessfully)
            {
                throw new Exception("The asset conversion operation completed with an unexpected successful status");
            }

            // ScaledAssetDimensions should be null when asset conversion fails due to an invalid asset file format
            // But should not throw an exception trying to access it
            if (operation.Value.ScaledAssetDimensions != null)
            {
                throw new Exception("ScaledAssetDimensions isn't null for a failed job on an invalid asset");
            }
        }
Ejemplo n.º 11
0
        public async Task <int> RunJob(string jobId = "")
        {
            int returnValue = 0;

            try
            {
                using AzureEventSourceListener listener = new AzureEventSourceListener(
                          (e, message) => configuration.Logger.LogInformation("[{0:HH:mm:ss:fff}][{1}] {2}", DateTimeOffset.Now, e.Level, message),
                          level: EventLevel.Verbose);

                // Initialize Object Anchors client
                ObjectAnchorsConversionClient client = new ObjectAnchorsConversionClient(Guid.Parse(configuration.AccountId), configuration.AccountDomain, new AzureKeyCredential(configuration.AccountKey));

                AssetConversionOperation conversionOperation = null;
                if (string.IsNullOrEmpty(jobId))
                {
                    Console.WriteLine($"Asset   : {configuration.InputAssetPath}");
                    Console.WriteLine($"Gravity : {configuration.Gravity}");
                    Console.WriteLine($"Unit    : {Enum.GetName(typeof(AssetLengthUnit), configuration.AssetDimensionUnit)}");

                    // Upload our asset
                    Console.WriteLine("Attempting to upload asset...");
                    Uri        assetUri         = (await client.GetAssetUploadUriAsync()).Value.UploadUri;
                    BlobClient uploadBlobClient = new BlobClient(assetUri);
                    using (FileStream fs = File.OpenRead(configuration.InputAssetPath))
                    {
                        await uploadBlobClient.UploadAsync(fs);
                    }

                    // Schedule our asset conversion job specifying:
                    // - The uri to our uploaded asset
                    // - Our asset file format
                    // - Gravity direction of 3D asset
                    // - The unit of measurement of the 3D asset
                    Console.WriteLine("Attempting to create asset conversion job...");
                    var assetOptions = new AssetConversionOptions(
                        assetUri,
                        AssetFileType.FromFilePath(configuration.InputAssetPath),
                        configuration.Gravity,
                        configuration.AssetDimensionUnit);
                    conversionOperation = await client.StartAssetConversionAsync(assetOptions);

                    jobId = conversionOperation.Id;
                    Console.WriteLine($"Successfully created asset conversion job. Job ID: {jobId}");
                }
                else
                {
                    conversionOperation = new AssetConversionOperation(Guid.Parse(jobId), client);
                }

                // Wait for job to complete
                Console.WriteLine("Waiting for job completion...");
                var response = await conversionOperation.WaitForCompletionAsync(new CancellationTokenSource((int)configuration.WaitForJobCompletionTimeout.TotalMilliseconds).Token);

                returnValue = EvaluateJobResults(response.Value);

                if (response.Value.ConversionStatus == AssetConversionStatus.Succeeded)
                {
                    string outputPath = Path.Combine(Path.GetDirectoryName(configuration.InputAssetPath), Path.GetFileNameWithoutExtension(configuration.InputAssetPath) + "_" + jobId + ".ou");
                    Console.WriteLine($"Attempting to download result as '{outputPath}'...");
                    BlobClient downloadBlobClient = new BlobClient(response.Value.OutputModelUri);
                    await downloadBlobClient.DownloadToAsync(outputPath);

                    Console.WriteLine("Success!");
                }
            }
            catch (TaskCanceledException)
            {
                returnValue = 1;
                Console.Error.WriteLine($"Timed out waiting for your job to complete.");
            }
            catch (RequestFailedException e)
            {
                returnValue = 1;
                Console.Error.WriteLine($"\nYour request failed:\n\n{e.Message}");
            }
            catch (Exception e)
            {
                returnValue = 1;
                Console.Error.WriteLine($"\n{e.GetType().Name}:\n{e.Message}");
            }

            return(returnValue);
        }
Ejemplo n.º 12
0
        public async Task <(int result, string jobId)> RunJob(string jobId = "")
        {
            int returnValue = 0;

            try
            {
                using AzureEventSourceListener listener = new AzureEventSourceListener(
                          (e, message) => configuration.Logger.LogInformation("[{0:HH:mm:ss:fff}][{1}] {2}", DateTimeOffset.Now, e.Level, message),
                          level: EventLevel.Verbose);

                // Initialize Object Anchors client
                ObjectAnchorsConversionClient client = new ObjectAnchorsConversionClient(Guid.Parse(configuration.AccountId), configuration.AccountDomain, new AzureKeyCredential(configuration.AccountKey));

                AssetConversionOperation conversionOperation = null;
                if (string.IsNullOrEmpty(jobId))
                {
                    Console.WriteLine($"Asset   : {configuration.InputAssetPath}");
                    Console.WriteLine($"Gravity : {configuration.Gravity}");
                    Console.WriteLine($"Unit    : {Enum.GetName(typeof(AssetLengthUnit), configuration.AssetDimensionUnit)}");

                    // Upload our asset
                    Console.WriteLine("Attempting to upload asset...");
                    Uri assetUri = (await client.GetAssetUploadUriAsync()).Value.UploadUri;
                    Console.WriteLine($"\tUpload Uri: {assetUri}");
                    BlobClient uploadBlobClient = new BlobClient(assetUri, new BlobClientOptions
                    {
                        // The default timeout for HttpClient and RetryOptions.NetworkTimeout is 100 seconds.
                        // Increasing to 5 minutes allows for more flexibility when uploading assets
                        Transport = new HttpClientTransport(new HttpClient {
                            Timeout = TimeSpan.FromMinutes(5)
                        }),
                        Retry = { NetworkTimeout = TimeSpan.FromMinutes(5) }
                    });
                    await UploadBlobAsync(uploadBlobClient, configuration.InputAssetPath);

                    Console.WriteLine("\nAsset uploaded");

                    // Schedule our asset conversion job specifying:
                    // - The uri to our uploaded asset
                    // - Our asset file format
                    // - Gravity direction of 3D asset
                    // - The unit of measurement of the 3D asset
                    Console.WriteLine("Attempting to create asset conversion job...");
                    AssetConversionOptions assetOptions = new AssetConversionOptions(
                        assetUri,
                        AssetFileType.FromFilePath(configuration.InputAssetPath),
                        configuration.Gravity,
                        configuration.AssetDimensionUnit);
                    conversionOperation = await client.StartAssetConversionAsync(assetOptions);

                    jobId = conversionOperation.Id;
                    Console.WriteLine($"Successfully created asset conversion job. Job ID: {jobId}");
                }
                else
                {
                    conversionOperation = new AssetConversionOperation(Guid.Parse(jobId), client);
                }

                // Wait for job to complete
                Console.WriteLine("Waiting for job completion...");
                Response <AssetConversionProperties> response = await conversionOperation.WaitForCompletionAsync(new CancellationTokenSource((int)configuration.WaitForJobCompletionTimeout.TotalMilliseconds).Token);

                Console.WriteLine(
                    $"\nAsset dimensions calculated during conversion (in meters): " +
                    $"({(response.Value.ScaledAssetDimensions?.X.ToString() ?? "NULL")}," +
                    $" {(response.Value.ScaledAssetDimensions?.Y.ToString() ?? "NULL")}," +
                    $" {(response.Value.ScaledAssetDimensions?.Z.ToString() ?? "NULL")})");

                returnValue = EvaluateJobResults(response.Value);

                if (response.Value.ConversionStatus == AssetConversionStatus.Succeeded)
                {
                    string tempFolderPath   = Path.GetTempPath();
                    string outputFolderPath = Path.GetDirectoryName(configuration.InputAssetPath);
                    string zipFilePath      = Path.Combine(tempFolderPath, Path.GetFileNameWithoutExtension(configuration.InputAssetPath) + "_" + jobId + ".zip");
                    Console.WriteLine($"Attempting to download zip result here: '{zipFilePath}' ...");
                    BlobClient downloadBlobClient = new BlobClient(response.Value.OutputModelUri);
                    await downloadBlobClient.DownloadToAsync(zipFilePath);

                    Console.WriteLine($"Unzipping '{zipFilePath}' to '{outputFolderPath}' ...");
                    ZipFile.ExtractToDirectory(zipFilePath, outputFolderPath, overwriteFiles: true);
                    Console.WriteLine($"Success! Your OU Model is here: '{outputFolderPath}\\{jobId.ToUpperInvariant()}.ou'");
                    File.Delete(zipFilePath);
                }
                else
                {
                    ConversionErrorCode errorCode = response.Value.ErrorCode;

                    if (errorCode == ConversionErrorCode.AssetCannotBeConverted)
                    {
                        Console.WriteLine("The asset was unable to be converted. Refer to asset conversion guidelines.");
                    }
                    else if (errorCode == ConversionErrorCode.AssetDimensionsOutOfBounds)
                    {
                        Console.WriteLine("Asset dimensions exceeded those allowed for an asset to be converted.");
                    }
                    else if (errorCode == ConversionErrorCode.AssetSizeTooLarge)
                    {
                        Console.WriteLine("The size of the asset file was too large. Refer to asset conversion guidelines for the maximum allowed size.");
                    }
                    else if (errorCode == ConversionErrorCode.InvalidAssetUri)
                    {
                        Console.WriteLine("The URI provided didn't link to an uploaded asset for conversion.");
                    }
                    else if (errorCode == ConversionErrorCode.InvalidFaceVertices)
                    {
                        Console.WriteLine("The uploaded asset included references to vertices that don't exist. Ensure the asset file is correctly formed.");
                    }
                    else if (errorCode == ConversionErrorCode.InvalidGravity)
                    {
                        Console.WriteLine("The provided gravity vector for the asset was incorrect. Ensure it is not the default all-zero vector.");
                    }
                    else if (errorCode == ConversionErrorCode.InvalidJobId)
                    {
                        Console.WriteLine("The provided job ID doesn't exist.");
                    }
                    else if (errorCode == ConversionErrorCode.InvalidScale)
                    {
                        Console.WriteLine("The provided scale for the asset was either zero or negative.");
                    }
                    else if (errorCode == ConversionErrorCode.TooManyRigPoses)
                    {
                        Console.WriteLine("The provided asset had more rig poses than is permitted for an asset to be converted. Refer to asset conversion guidelines for the maximum allowed size.");
                    }
                    else if (errorCode == ConversionErrorCode.ZeroFaces)
                    {
                        Console.WriteLine("The provided asset had no faced. Ensure the asset file is correctly formed.");
                    }
                    else if (errorCode == ConversionErrorCode.ZeroTrajectoriesGenerated)
                    {
                        Console.WriteLine("The provided asset was determined to have no trajectories generated. Ensure the asset file is correctly formed.");
                    }
                    else
                    {
                        Console.WriteLine("An unexpected error was encountered. If the issue persists, reach out to customer support.");
                    }
                }
            }
            catch (AssetFileTypeNotSupportedException ex)
            {
                returnValue = 1;
                string supportedFileTypeList = string.Join(", ", ex.SupportedAssetFileTypes);
                Console.Error.WriteLine($"The provided asset file of type {ex.AttemptedFileType} is not supported. Supported file types include {supportedFileTypeList}.");
            }
            catch (TaskCanceledException)
            {
                returnValue = 1;
                Console.Error.WriteLine($"Timed out waiting for your job to complete.");
            }
            catch (RequestFailedException e)
            {
                returnValue = 1;
                Console.Error.WriteLine($"\nYour request failed:\n\n{e.Message}");
            }
            catch (Exception e)
            {
                returnValue = 1;
                PrintException(e);
            }

            return(result : returnValue, jobId : jobId);
        }