Sane C++ Libraries
C++ Platform Abstraction Libraries
Loading...
Searching...
No Matches
ProcessErrorFormatter.h
1// Copyright (c) Stefano Cristiano
2// SPDX-License-Identifier: MIT
3#pragma once
4#include "../Common/ResultErrorFormatter.h"
5#include "ProcessError.h"
6
7namespace SC
8{
11
12namespace detail
13{
14inline bool appendProcessErrorDetail(ResultErrorFormatter& formatter, ProcessErrorDetail detail)
15{
16 switch (detail)
17 {
18 case ProcessErrorDetail::None: return true;
19 case ProcessErrorDetail::PosixWaitPid: formatter.append("POSIX wait for child"); break;
20 case ProcessErrorDetail::WindowsGetExitCodeProcess: formatter.append("Windows query process exit code"); break;
21 case ProcessErrorDetail::PosixFork: formatter.append("POSIX create child process"); break;
22 case ProcessErrorDetail::PosixExec: formatter.append("POSIX execute program"); break;
23 case ProcessErrorDetail::PosixBuildResolveExecutablePath: formatter.append("POSIX build executable path"); break;
24 case ProcessErrorDetail::PosixDuplicateDescriptor: formatter.append("POSIX duplicate file descriptor"); break;
25 case ProcessErrorDetail::PosixResetSignalHandlers: formatter.append("POSIX reset signal handlers"); break;
26 case ProcessErrorDetail::PosixChangeWorkingDirectory: formatter.append("POSIX change working directory"); break;
27 case ProcessErrorDetail::WindowsSetHandleInformation: formatter.append("Windows prepare inherited handle"); break;
28 case ProcessErrorDetail::WindowsCreateProcess: formatter.append("Windows create process"); break;
29 case ProcessErrorDetail::WindowsRtlCloneUserProcess: formatter.append("Windows clone process"); break;
30 case ProcessErrorDetail::WindowsNtWaitForSingleObject: formatter.append("Windows wait for child"); break;
31 case ProcessErrorDetail::WindowsResolveWorkingDirectory:
32 formatter.append("Windows resolve working directory");
33 break;
34 case ProcessErrorDetail::WindowsPrepareExecutableTransportPath:
35 formatter.append("Windows prepare executable path for launch");
36 break;
37 case ProcessErrorDetail::WindowsPrepareWorkingDirectoryTransportPath:
38 formatter.append("Windows prepare working directory for launch");
39 break;
40 case ProcessErrorDetail::WindowsNormalizeExecutablePath:
41 formatter.append("Windows normalize executable path");
42 break;
43 default: return false;
44 }
45 return true;
46}
47
48inline ResultErrorFormat formatProcessErrorWithDetails(ProcessError error, ProcessErrorDetail detail,
49 uint32_t nativeError, Span<char> output)
50{
51 ResultErrorFormatter formatter(output);
52 switch (error)
53 {
54 case ProcessError::ProcessChainEmpty: formatter.append("Process chain has no processes"); break;
55 case ProcessError::ProcessAlreadyInChain: formatter.append("Process already belongs to a process chain"); break;
56 case ProcessError::InvalidInputRedirection: formatter.append("Process input redirection is invalid"); break;
57 case ProcessError::InvalidOutputRedirection: formatter.append("Process output redirection is invalid"); break;
58 case ProcessError::UnsupportedInputRedirection: formatter.append("Process input redirection is unsupported"); break;
59 case ProcessError::UnsupportedOutputRedirection:
60 formatter.append("Process output redirection is unsupported");
61 break;
62 case ProcessError::ArgumentCapacityExceeded: formatter.append("Process argument capacity exceeded"); break;
63 case ProcessError::EnvironmentCapacityExceeded: formatter.append("Process environment capacity exceeded"); break;
64 case ProcessError::WaitFailed: formatter.append("Failed to wait for process"); break;
65 case ProcessError::LaunchFailed: formatter.append("Failed to launch process"); break;
66 case ProcessError::CloneFailed: formatter.append("Failed to clone process"); break;
67 case ProcessError::PathCapacityExceeded: formatter.append("Process path capacity exceeded"); break;
68 case ProcessError::PathMustBeAbsolute: formatter.append("Process path must be absolute"); break;
69 case ProcessError::InvalidPath: formatter.append("Process path is invalid"); break;
70 case ProcessError::PathResolutionFailed: formatter.append("Failed to resolve process path"); break;
71 default: return ResultErrorFormatter::failure(ResultErrorFormatStatus::UnknownError, output);
72 }
73
74 if (detail != ProcessErrorDetail::None)
75 {
76 formatter.append(" (detail: ");
77 if (not appendProcessErrorDetail(formatter, detail))
78 return ResultErrorFormatter::failure(ResultErrorFormatStatus::UnknownError, output);
79 if (nativeError != 0)
80 {
81 formatter.append(", native error: ");
82 formatter.append(static_cast<uint64_t>(nativeError));
83 }
84 formatter.append(")");
85 }
86 else if (nativeError != 0)
87 {
88 formatter.append(" (native error: ");
89 formatter.append(static_cast<uint64_t>(nativeError));
90 formatter.append(")");
91 }
92 return formatter.finish();
93}
94} // namespace detail
95
97inline ResultErrorFormat formatProcessError(ProcessError error, Span<char> output)
98{
99 return detail::formatProcessErrorWithDetails(error, ProcessErrorDetail::None, 0, output);
100}
101
103inline ResultErrorFormat formatProcessError(Result result, Span<char> output)
104{
105 if (result)
106 return ResultErrorFormatter::failure(ResultErrorFormatStatus::NotAnError, output);
107 if (result.category() != ProcessResultCategory)
108 return ResultErrorFormatter::failure(ResultErrorFormatStatus::ForeignCategory, output);
109 return formatProcessError(static_cast<ProcessError>(result.errorValue()), output);
110}
111
113inline ResultErrorFormat formatProcessError(ResultProcess result, Span<char> output)
114{
115 if (result)
116 return ResultErrorFormatter::failure(ResultErrorFormatStatus::NotAnError, output);
117 if (result.result.category() != ProcessResultCategory)
118 return ResultErrorFormatter::failure(ResultErrorFormatStatus::ForeignCategory, output);
119 return detail::formatProcessErrorWithDetails(static_cast<ProcessError>(result.result.errorValue()), result.detail,
120 result.nativeError, output);
121}
122
124} // namespace SC
ProcessErrorDetail
Stable diagnostic stages for Process failures.
Definition ProcessError.h:35
ProcessError
Stable error codes returned by the Process library.
Definition ProcessError.h:14
ResultErrorFormat formatProcessError(ProcessError error, Span< char > output)
Formats a canonical English Process diagnostic into caller-owned storage.
Definition ProcessErrorFormatter.h:97
Process result retaining optional backend and native platform details.
Definition ProcessError.h:62