{"record":{"id":"e38fd9f4ec8caa04","repo":"Tichau/FileConverter","slug":"the-conversion-preset-must-be-valid","errorCode":null,"errorMessage":"The conversion preset must be valid.","messagePattern":"The conversion preset must be valid\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"Application/FileConverter/ConversionJobs/ConversionJob_Excel.cs","lineNumber":94,"sourceCode":"            }\n            else\n            {\n                // Generate intermediate file path.\n                string fileName = Path.GetFileNameWithoutExtension(this.InputFilePath);\n                string tempPath = Path.GetTempPath();\n                this.intermediateFilePath = PathHelpers.GenerateUniquePath(tempPath + fileName + \".pdf\");\n\n                ConversionPreset intermediatePreset = new ConversionPreset(\"Pdf to image\", this.ConversionPreset, \"pdf\");\n                this.pdf2ImageConversionJob = ConversionJobFactory.Create(intermediatePreset, this.intermediateFilePath);\n                this.pdf2ImageConversionJob.PrepareConversion(this.OutputFilePaths);\n            }\n        }\n\n        protected override void Convert()\n        {\n            if (this.ConversionPreset == null)\n            {\n                throw new System.Exception(\"The conversion preset must be valid.\");\n            }\n\n            this.UserState = Properties.Resources.ConversionStateReadDocument;\n\n            if (!this.TryLoadDocumentIfNecessary())\n            {\n                this.ConversionFailed(Properties.Resources.ErrorUnableToUseMicrosoftOffice);\n                return;\n            }\n\n            // Make this document the active document.\n            this.document.Activate();\n\n            this.UserState = Properties.Resources.ConversionStateConversion;\n\n            Debug.Log(\"Convert excel document to pdf.\");\n            this.document.ExportAsFixedFormat(Excel.Enums.XlFixedFormatType.xlTypePDF, this.intermediateFilePath);\n","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/Tichau/FileConverter/blob/6c157a411fb70fb7440d2e3b226042781fd55b15/Application/FileConverter/ConversionJobs/ConversionJob_Excel.cs#L76-L112","documentation":"ConversionJob_Excel.Convert() is a defensive invariant guard: it throws System.Exception when this.ConversionPreset is null before driving the NetOffice Excel interop (load workbook, export intermediate PDF, then pdf2Image sub-job). The real constructor ConversionJob(ConversionPreset, string) at ConversionJob.cs:42 already rejects a null preset with ArgumentNullException, so under the public API this guard is only reachable through the parameterless ConversionJob_Excel() : base() design-mode constructor (ConversionJob.cs:26) which deliberately sets ConversionPreset = null. Hitting it therefore signals misuse (wrong constructor, reflection, or a unit test calling protected Convert() directly) rather than a normal runtime failure.","triggerScenarios":"An instance built via the parameterless ConversionJob_Excel() (XAML designer / 'Design Mode') has Convert() invoked; or reflection/dynamic dispatch bypasses the (preset, inputFilePath) constructor, leaving ConversionPreset null when Convert() runs. StartConversion() itself would normally throw 'Invalid conversion state' first because the design-mode ctor sets State=InProgress, so direct Convert() invocation is the realistic path.","commonSituations":"XAML designer previewing a ConversionJob_Excel instance; a unit test that new's the parameterless ctor and calls Convert(); a future subclass that adds a constructor without chaining the preset; Office interop code that constructed the job before a preset was loaded from Settings.","solutions":["Construct via the real ctor: new ConversionJob_Excel(conversionPreset, inputFilePath) — it throws ArgumentNullException early if the preset is null.","Never call the protected Convert() directly; drive the job through PrepareConversion() then StartConversion(), which enforce the Ready state.","If you must use the parameterless ctor (design time), gate it with if (ConversionPreset == null) return; before any conversion logic.","Audit callers to confirm the preset was loaded successfully from Settings.user.xml before the job is created."],"exampleFix":"// before (design-mode ctor, then convert)\nvar job = new ConversionJob_Excel();\njob.Convert(); // throws: preset null\n\n// after\nvar job = new ConversionJob_Excel(conversionPreset, inputFilePath);\njob.PrepareConversion(outputPaths);\njob.StartConversion();","handlingStrategy":"validation","validationCode":"// Run before StartConversion / Convert\nif (job == null || job.ConversionPreset == null)\n{\n    throw new InvalidOperationException(\n        \"ConversionJob_Excel requires a non-null ConversionPreset; use the (preset, inputFilePath) constructor.\");\n}\njob.StartConversion();","typeGuard":"private static bool HasValidPreset(ConversionJob job) => job != null && job.ConversionPreset != null;","tryCatchPattern":"try\n{\n    job.StartConversion();\n}\ncatch (Exception ex) when (ex.Message.Contains(\"conversion preset must be valid\"))\n{\n    // Preset invariant violated: rebuild the job with a loaded preset, or fail the batch entry gracefully.\n    logger.Error(ex, \"Excel job created without a preset; reconstructing.\");\n    job = new ConversionJob_Excel(LoadPreset(), inputPath);\n}","preventionTips":["Always construct ConversionJob subclasses with the (ConversionPreset, string) overload; reserve the parameterless ctor for XAML design time only.","Never invoke the protected Convert() directly; use PrepareConversion() then StartConversion().","Load and validate the ConversionPreset from Settings.user.xml once at startup and pass the same instance to the factory.","Add a unit test asserting ConversionPreset != null for every job created via ConversionJobFactory.Create."],"tags":["csharp","fileconverter","conversion-preset","null-check","defensive-guard","excel","office-interop"],"backgroundTag":null,"analyzedSha":"6c157a411fb70fb7440d2e3b226042781fd55b15","analyzedAt":"2026-08-13T15:04:08.307Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}