-
Notifications
You must be signed in to change notification settings - Fork 879
Description
Describe the bug
When I run docfx build from within MSBuild, and DocFX terminates because of an exception, the stack trace is difficult to read because of numerous line breaks at unexpected positions.
To Reproduce
Steps to reproduce the behavior:
- Use Git Bash on Windows.
mkdir -p /c/Projects/docfx-democd /c/Projects/docfx-demodotnet new global.json --sdk-version=8.0.100 --roll-forward=featuredotnet new tool-manifestdotnet tool install --local --version=2.78.4 docfxdotnet docfx init. Accept defaults, except answernto Generate .NET API documentation? [y/n] (y) and Enable PDF? [y/n] (y).- Create
docs.msbuildprojwith this content:<Project Sdk="Microsoft.Build.NoTargets/3.7.56"> <PropertyGroup> <TargetFramework>netstandard2.0</TargetFramework> </PropertyGroup> <Target Name="DocFx" AfterTargets="Build"> <Delete Files="obj/docfx.log.json" /> <Exec UseCommandProcessor="false" Command='dotnet docfx build --log "obj/docfx.log.json"' /> </Target> </Project>
dotnet build docs.msbuildproj# Succeeds.exec 9< _site/index.html# Open the file to provoke IOException.dotnet build docs.msbuildproj# Fails, and shows a stack trace.
Current behavior
The stack trace of the exception is difficult to read, because of excessive line breaks both between and within words:
$ dotnet build docs.msbuildproj
Determining projects to restore...
All projects are up-to-date for restore.
Searching built-in plugins in directory C:\Users\Kalle\.nuget\packages\docfx\2.78.4\tools\
net8.0\any\...
Post processor ExtractSearchIndex loaded.
No files are found with glob pattern images/**, excluding <none>, under directory "C:\Proj
ects\docfx-demo"
7 plug-in(s) loaded.
ExtractSearchIndex: UseMetadata = False, UseMetadataTitle = True
Building 2 file(s) in TocDocumentProcessor(BuildTocDocument)...
Building 3 file(s) in ConceptualDocumentProcessor(BuildConceptualDocument=>ValidateConcept
ualDocumentMetadata)...
Applying templates to 5 model(s)...
AggregateException: One or more errors occurred. (The process cannot access
the
file 'C:\Projects\docfx-demo\_site\index.html' because it is being used by
another process.)
IOException: The process cannot access the file
'C:\Projects\docfx-demo\_site\index.html' because it is being used by
another process.
at SafeFileHandle CreateFile(
string fullPath, FileMode mode, FileAccess
access, FileShare share, FileOptions
options)
at SafeFileHandle Open(stri
ng fullPath, FileMode mode, FileAccess
38;5;8maccess,
FileShare share, FileOptions options
, long preallocationSize,
UnixFileMode? unixCreateMode)
at ctor(string path,
FileMode mode, FileAccess access, Fil
eShare share,
FileOptions options, long preallocatio
nSize, UnixFileMode?
unixCreateMode)
at FileStreamStrategy ChooseStrategyCore(
0mstring path, FileMode mode,
FileAccess access, FileShare share
, FileOptions options, long
preallocationSize, UnixFileMode? unixCreateMode
)
at FileStream Create(string
path)
at Stream Create(RelativePa
th file) in RealFileWriter.cs:
27
at Stream Create(RelativePa
th file) in FileAbstractLayer.cs
:46
at Stream Create(string
file) in FileAbstractLayer.cs:
38;5;251m82
at Stream Create(string
file) in RootedFileAbstractLayer.cs
:34
at void TransformDocument(s
tring result, string extension,
IDocumentBuildContext context, string
destFilePath, ManifestItem
manifestItem, out List<XRefDetails> unresolvedXRefs
) in
TemplateModelTransformer.cs:268
at ManifestItem Transform(I
nternalManifestItem item) in
TemplateModelTransformer.cs:151
at void <ProcessCore>b__0(I
nternalManifestItem item) in
TemplateProcessor.cs:190
at void <RunAll>b__0(TEleme
nt s) in DocumentExceptionExtensions.cs
:91
at void <ForWorker>b__1(ref
RangeWorker currentWorker, long timeout, ou
t
bool replicationDelegateYieldedBeforeCompletion)
at void <ForWorker>b__1(ref
RangeWorker currentWorker, long timeout, ou
t
bool replicationDelegateYieldedBeforeCompletion)
at void Execute()
at void Run<TState>(Replicatable
UserAction<TState> action, ParallelOptions
options, bool stopOnFirstFailure)
at ParallelLoopResult ForWorker<TLocal,TInt>(
TInt fromInclusive, TInt
toExclusive, ParallelOptions parallelOptions,
Action<TInt> body,
Action<TInt, ParallelLoopState> bodyWithState, Func<TInt
,
ParallelLoopState, TLocal, TLocal> bodyWithLocal, Func<T
Local> localInit,
Action<TLocal> localFinally)
at ParallelLoopResult ForWorker<TLocal,TInt>(
TInt fromInclusive, TInt
toExclusive, ParallelOptions parallelOptions,
Action<TInt> body,
Action<TInt, ParallelLoopState> bodyWithState, Func<TInt
,
ParallelLoopState, TLocal, TLocal> bodyWithLocal, Func<T
Local> localInit,
Action<TLocal> localFinally)
at ParallelLoopResult ForEachWorker<TSource,TLocal>
(IEnumerable<TSource>
source, ParallelOptions parallelOptions, Ac
tion<TSource> body,
Action<TSource, ParallelLoopState> bodyWithState, Action
<TSource,
ParallelLoopState, long> bodyWithStateAndIndex, Func<TSo
urce,
ParallelLoopState, TLocal, TLocal> bodyWithStateAndLocal,
Func<TSource,
ParallelLoopState, long, TLocal, TLocal> bodyWithEverything,
Func<TLocal>
localInit, Action<TLocal> localFinally)
at ParallelLoopResult ForEach<TSource>(
IEnumerable<TSource> source,
ParallelOptions parallelOptions, Action<TSource>
body)
at void RunAll<TElement>(IEnumer
able<TElement> elements, Action<TElement>
action, int parallelism, CancellationToken
0m cancellationToken) in
DocumentExceptionExtensions.cs:80
at void RunAll<TElement>(IReadOn
lyList<TElement> elements, Action<TElement>
action, int parallelism, CancellationToken
0m cancellationToken) in
DocumentExceptionExtensions.cs:68
at List<ManifestItem> ProcessCore(
List<InternalManifestItem> items,
ApplyTemplateSettings settings, IDictionary<string, obje
ct> globals) in
TemplateProcessor.cs:185
at List<ManifestItem> Process(Li
st<InternalManifestItem> manifest,
ApplyTemplateSettings settings, IDictionary<string, obje
ct> globals) in
TemplateProcessor.cs:82
at List<ManifestItem> ProcessTemplate()
in ManifestProcessor.cs:186
at void Process() in
ManifestProcessor.cs:53
at void Handle(List<HostService>
hostServices, int maxParallelism)
in
LinkPhaseHandler.cs:32
at Manifest Build(DocumentBuildP
arameters parameters, IMarkdownService
markdownService, CancellationToken cancellationToken
) in
SingleDocumentBuilder.cs:70
at void Build(IList<DocumentBuil
dParameters> parameters, string
outputDirectory, CancellationToken cancellationToken
) in DocumentBuilder.cs
:123
at void BuildDocument(BuildJsonC
onfig config, BuildOptions options,
TemplateManager templateManager, string bas
eDirectory, string
outputDirectory, string templateDirectory,
CancellationToken
cancellationToken) in DocumentBuilderWrapper
.cs:42
at string Exec(BuildJsonConfig
config, BuildOptions options, string
configDirectory, string outputDirectory, Ca
ncellationToken
cancellationToken) in RunBuild.cs
:39
at void <Execute>b__0() in
BuildCommand.cs:25
at int Run(LogOptions
options, Action run) in Com
mandHelper.cs:48
at int Execute(CommandContext
context, BuildCommandOptions settings)
in
BuildCommand.cs:15
at Task<int> Execute(CommandCont
ext context, CommandSettings settings)
in
CommandOfT.cs:40
at async Task<int> Execute(Comma
ndTree leaf, CommandTree tree, CommandContex
t
context, ITypeResolver resolver, IConfigura
tion configuration) in
CommandExecutor.cs:259
C:\Projects\docfx-demo\docs.msbuildproj(8,5): error MSB3073: The command "dotnet docfx build --log "ob
j/docfx.log.json"" exited with code -1.
Build FAILED.
C:\Projects\docfx-demo\docs.msbuildproj(8,5): error MSB3073: The command "dotnet docfx build --log "ob
j/docfx.log.json"" exited with code -1.
0 Warning(s)
1 Error(s)
Time Elapsed 00:00:03.10
There is some highlighting of method names and parameter names; perhaps that causes MSBuild to overestimate the lengths of the lines:
Expected behavior
Display a readable stack trace.
A documented command-line option that disables Spectre.Console output formatting altogether and just writes the plain Exception.ToString() to Console.Error would suffice. It would be easy to add that to MSBuild Exec task invocations.
Context (please complete the following information):
- OS: Windows 11 version 25H2
- Docfx version: [e.g. 2.59.0] 2.78.4
- MSBuild version: 17.11.48+02bf66295
- .NET SDK version: 8.0.416 (roll-forward from 8.0.100)
Additional context
Related to #9457, but that issue was for warnings, while this one is for exception stack traces.
Adding EnvironmentVariables="NO_COLOR=1" or EnvironmentVariables="TERM=dumb" to the Exec task invocation makes the output a lot nicer. (NO_COLOR=1 still uses a bold font for exception messages and file names, whle TERM=dumb doesn't.) However, DocFX does not document these, and the stack trace still has extra line breaks if the console is fewer than 83 columns wide.