Policy for message structure #18423
Replies: 2 comments 3 replies
-
If we're going in this direction, it would be great to enumerate errors ("Error E0053") and link to a page describing how to fix the error? That's a lot of work though. |
Beta Was this translation helpful? Give feedback.
-
Centralised/more-consistent diagnostic formatting would be great!
I can't tell if you're thinking along these lines, but it might make sense to reify these into objects, rather than just direct string formatting and passing those strings around. This opens up options like more output formats (e.g. structured JSON output for potential editor integration). The Rust compiler has a reputation as having good error messages, and they do something like this. For instance, AFAIK, all diagnostics build a There's a fluent builder interface (https://github.com/rust-lang/rust/blob/38b96553112dce3de630890701f17d86e265f6ba/compiler/rustc_errors/src/diagnostic_builder.rs) that's typically used to build these, e.g. https://github.com/rust-lang/rust/blob/38b96553112dce3de630890701f17d86e265f6ba/compiler/rustc_hir_typeck/src/cast.rs#L549-L577 For instance, click for a possibility of a very very loose API translation of that.# basic data types
class DiagnosticLevel(enum.Enum):
ERROR = enum.auto()
WARNING = enum.auto()
NOTE = enum.auto()
HELP = enum.auto()
@dataclass
class CodeLocation:
file: str
line: int
column: int
@dataclass
class CodeSpan:
start: CodeLocation
end: CodeLocation
class SubDiagnostic:
level: DiagnosticLevel
span: CodeSpan
message: str
@dataclass
class Diagnostic:
level: DiagnosticLevel
span: CodeSpan
message: str
code: int
sub_diagonstic: SubDiagnostic
# things to use it
class DiagnosticBuilder:
def span_note(self, span: CodeSpan, message: str) -> DiagnosticBuilder:
"""adds a sub-diagnostic at NOTE level associated with a particular span"""
...
def help(self, message: str) -> DiagnosticBuilder:
"""adds a sub-diagnostic at HELP level"""
...
# ...various other helpers...
def finish(self) -> Diagnostic:
...
class DiagnosticManager:
@contextmanager
def error_builder(self, span: CodeSpan, message: str, code: int) -> Iterator[DiagnosticBuilder]:
builder = DiagnosticBuilder(...)
yield builder
self.emit(builder.finish())
# ...various other helpers...
# could be used like
with diagnostic_manager.error_builder(span_for_target, "failed to process according to requested parameters", code=123) as diag:
diag.span_note(span_for_parameters, "The processing request for parameters `a`, `b` and `c` during step `frobnicator`")
diag.help("See `ref` for common issues during `frobnicator` processing.") One can presumably start with something smaller than the full set of infrastructure rustc has. |
Beta Was this translation helpful? Give feedback.
-
With an increasing number of messages that Pants may present to its users, it would be helpful if there was a common structure to them, a message structure policy if you will. Both informational as well as error messages could benefit from a pre determined structure designed to be clear concise and to the point. This also makes it easier for users to recognize the various parts of a message they have not seen before simply by being familiar with how they are structured.
For the above, I'm opening this discussion so we can decide if/what we would want to achieve in this space, with the following proposal:
To help make sure the policy is followed, and more importantly make it easier to adjust over time, we should have a common framework for constructing these messages. This will also save on development where less time needs to be spent on figuring out how to properly format messages.
The "message format framework" would take as inputs (based on applicability) a subject, verb-sentence, context and "next steps"/help.
Possible message structure could be:
This opens up the message with what it is about, and why, followed by some additional context and ends with some possible corrective or possible further action to take.
Example with some made up content:
Beta Was this translation helpful? Give feedback.
All reactions