Skip to content

Commit 44e7368

Browse files
humitosagjohnson
andauthored
Notifications: improve copy on error messages (#11062)
* Notifications: de-duplicate/standardize concurrency limit reached * Notifications: improve copy * Remove unused `message_id` * Improve missing/not found `mkdocs.yml` file Closes #7707 * Improve `sphinx.configuration` file not found error message This validation should eventually happen at the Read the Docs config file. We are not there, but at least we are giving a better error message to users. Closes #8352 * Improve copy for error messages * Pass `format_values` to format the filename properly in the message * Apply suggestions from code review Co-authored-by: Anthony <[email protected]> * Show the type of the received value * Better header * Lint * Render class name via custom template filter ``` In [4]: n.get_message().get_rendered_body() Out[4]: '\n\n\nConfig validation error in <code></code>.\nExpected a list, got type <code>int</code> (<code>422</code>).' ``` * Make the title clearer * Remove "\n\n\n" due to tests failing --------- Co-authored-by: Anthony <[email protected]>
1 parent f72581c commit 44e7368

File tree

9 files changed

+106
-97
lines changed

9 files changed

+106
-97
lines changed

readthedocs/config/exceptions.py

-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ class ConfigError(BuildUserError):
1111
"config:python:use-system-site-packages-removed"
1212
)
1313
INVALID_VERSION = "config:base:invalid-version"
14-
GENERIC_INVALID_CONFIG_KEY = "config:key:generic-invalid-config-key"
1514
NOT_BUILD_TOOLS_OR_COMMANDS = "config:build:missing-build-tools-commands"
1615
BUILD_JOBS_AND_COMMANDS = "config:build:jobs-and-commands"
1716
APT_INVALID_PACKAGE_NAME_PREFIX = "config:apt:invalid-package-name-prefix"

readthedocs/config/notifications.py

+23-32
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@
2929
body=_(
3030
textwrap.dedent(
3131
"""
32-
No default configuration file found at repository's root.
32+
The required <code>readthedocs.yaml</code> configuration file was not found at repository's root.
33+
Learn how to use this file in our <a href="https://docs.readthedocs.io/en/stable/config-file/index.html">configuration file tutorial</a>.
3334
"""
3435
).strip(),
3536
),
@@ -66,8 +67,8 @@
6667
textwrap.dedent(
6768
"""
6869
The configuration key <code>python.system_packages</code> has been deprecated and removed.
69-
Refer to https://blog.readthedocs.com/drop-support-system-packages/ to read more
70-
about this change and how to upgrade your config file."
70+
<a href="https://blog.readthedocs.com/drop-support-system-packages/">Read our blog post</a>
71+
to learn more about this change and how to upgrade your configuration file."
7172
"""
7273
).strip(),
7374
),
@@ -80,8 +81,8 @@
8081
textwrap.dedent(
8182
"""
8283
The configuration key <code>python.use_system_site_packages</code> has been deprecated and removed.
83-
Refer to https://blog.readthedocs.com/drop-support-system-packages/ to read more
84-
about this change and how to upgrade your config file."
84+
<a href="https://blog.readthedocs.com/drop-support-system-packages/">Read our blog post</a>
85+
to learn more about this change and how to upgrade your configuration file."
8586
"""
8687
).strip(),
8788
),
@@ -99,29 +100,13 @@
99100
),
100101
type=ERROR,
101102
),
102-
Message(
103-
id=ConfigError.GENERIC_INVALID_CONFIG_KEY,
104-
header=_("Invalid configuration option"),
105-
body=_(
106-
textwrap.dedent(
107-
"""
108-
Invalid configuration option: <code>{{key}}</code>.
109-
110-
Read the Docs configuration file: <code>{{source_file}}</code>.
111-
112-
<code>{{error_message}}</code>
113-
"""
114-
).strip(),
115-
),
116-
type=ERROR,
117-
),
118103
Message(
119104
id=ConfigError.NOT_BUILD_TOOLS_OR_COMMANDS,
120-
header=_("Invalid configuration option: <code>build</code>"),
105+
header=_("Missing configuration option"),
121106
body=_(
122107
textwrap.dedent(
123108
"""
124-
At least one item should be provided in "tools" or "commands".
109+
At least one of the following configuration options is required: <code>build.tools</code> or <code>build.commands</code>.
125110
"""
126111
).strip(),
127112
),
@@ -169,19 +154,21 @@
169154
body=_(
170155
textwrap.dedent(
171156
"""
172-
You need to install your project with pip to use <code>extra_requirements</code>.
157+
You need to install your project with <code>python.install.method: pip</code>
158+
to use <code>python.install.extra_requirements</code>.
173159
"""
174160
).strip(),
175161
),
176162
type=ERROR,
177163
),
178164
Message(
179165
id=ConfigError.PIP_PATH_OR_REQUIREMENT_REQUIRED,
180-
header=_("Invalid configuration key"),
166+
header=_("Missing configuration key"),
181167
body=_(
182168
textwrap.dedent(
183169
"""
184-
<code>path</code> or <code>requirements</code> key is required for <code>python.install</code>.
170+
When using <code>python.install</code>,
171+
one of the following keys are required: <code>python.install.path</code> or <code>python.install.requirements</code>.
185172
"""
186173
).strip(),
187174
),
@@ -205,7 +192,7 @@
205192
body=_(
206193
textwrap.dedent(
207194
"""
208-
You can not have <code>exclude</code> and <code>include</code> submodules at the same time.
195+
You can not have <code>submodules.exclude</code> and <code>submodules.include</code> at the same time.
209196
"""
210197
).strip(),
211198
),
@@ -230,6 +217,7 @@
230217
textwrap.dedent(
231218
"""
232219
Error while parsing <code>{{filename}}</code>.
220+
Make sure your configuration file doesn't have any errors.
233221
234222
{{error_message}}
235223
"""
@@ -261,7 +249,8 @@
261249
textwrap.dedent(
262250
"""
263251
Config validation error in <code>{{key}}</code>.
264-
Expected one of (0, 1, true, false), got <code>{{value}}</code>.
252+
Expected one of <code>[0, 1, true, false]</code>, got type <code>{{value|to_class_name}}</code> (<code>{{value}}</code>).
253+
Make sure the type of the value is not a string.
265254
"""
266255
).strip(),
267256
),
@@ -274,7 +263,9 @@
274263
textwrap.dedent(
275264
"""
276265
Config validation error in <code>{{key}}</code>.
277-
Expected one of ({{choices}}), got <code>{{value}}</code>.
266+
Expected one of ({{choices}}), got type <code>{{value|to_class_name}}</code> (<code>{{value}}</code>).
267+
Double check the type of the value.
268+
A string may be required (e.g. <code>"3.10"</code> insted of <code>3.10</code>)
278269
"""
279270
).strip(),
280271
),
@@ -287,7 +278,7 @@
287278
textwrap.dedent(
288279
"""
289280
Config validation error in <code>{{key}}</code>.
290-
Expected a dictionary, got <code>{{value}}</code>.
281+
Expected a dictionary, got type <code>{{value|to_class_name}}</code> (<code>{{value}}</code>).
291282
"""
292283
).strip(),
293284
),
@@ -326,7 +317,7 @@
326317
textwrap.dedent(
327318
"""
328319
Config validation error in <code>{{key}}</code>.
329-
Expected a string, got <code>{{value}}</code>.
320+
Expected a string, got type <code>{{value|to_class_name}}</code> (<code>{{value}}</code>).
330321
"""
331322
).strip(),
332323
),
@@ -339,7 +330,7 @@
339330
textwrap.dedent(
340331
"""
341332
Config validation error in <code>{{key}}</code>.
342-
Expected a list, got <code>{{value}}</code>.
333+
Expected a list, got type <code>{{value|to_class_name}}</code> (<code>{{value}}</code>).
343334
"""
344335
).strip(),
345336
),

readthedocs/doc_builder/backends/mkdocs.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -168,9 +168,10 @@ def append_conf(self):
168168
value = []
169169
if not isinstance(value, list):
170170
raise MkDocsYAMLParseError(
171-
MkDocsYAMLParseError.INVALID_EXTRA_CONFIG.format(
172-
config=config,
173-
),
171+
message_id=MkDocsYAMLParseError.INVALID_EXTRA_CONFIG,
172+
format_values={
173+
"extra_config": config,
174+
},
174175
)
175176
# Add the static file only if isn't already in the list.
176177
value.extend([extra for extra in extras if extra not in value])

readthedocs/doc_builder/backends/sphinx.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,10 @@ def append_conf(self):
258258

259259
if not os.path.exists(self.config_file):
260260
raise UserFileNotFound(
261-
UserFileNotFound.FILE_NOT_FOUND.format(self.config_file)
261+
message_id=UserFileNotFound.FILE_NOT_FOUND,
262+
format_values={
263+
"filename": os.path.relpath(self.config_file, self.project_path),
264+
},
262265
)
263266

264267
# Allow symlinks, but only the ones that resolve inside the base directory.

readthedocs/doc_builder/exceptions.py

-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ class BuildAppError(BuildBaseException):
3535
class BuildUserError(BuildBaseException):
3636
GENERIC = "build:user:generic"
3737
SKIPPED_EXIT_CODE_183 = "build:user:exit-code-183"
38-
MAX_CONCURRENCY = "build:user:max-concurrency"
3938

4039
BUILD_COMMANDS_WITHOUT_OUTPUT = "build:user:output:no-html"
4140
BUILD_OUTPUT_IS_NOT_A_DIRECTORY = "build:user:output:is-no-a-directory"

readthedocs/doc_builder/python_environments.py

+8-6
Original file line numberDiff line numberDiff line change
@@ -291,9 +291,10 @@ def _append_core_requirements(self):
291291
)
292292
if not inputfile:
293293
raise UserFileNotFound(
294-
UserFileNotFound.FILE_NOT_FOUND.format(
295-
self.config.conda.environment
296-
)
294+
message_id=UserFileNotFound.FILE_NOT_FOUND,
295+
format_values={
296+
"filename": self.config.conda.environment,
297+
},
297298
)
298299
environment = parse_yaml(inputfile)
299300
except IOError:
@@ -334,9 +335,10 @@ def _append_core_requirements(self):
334335
)
335336
if not outputfile:
336337
raise UserFileNotFound(
337-
UserFileNotFound.FILE_NOT_FOUND.format(
338-
self.config.conda.environment
339-
)
338+
message_id=UserFileNotFound.FILE_NOT_FOUND,
339+
format_values={
340+
"filename": self.config.conda.environment,
341+
},
340342
)
341343
yaml.safe_dump(environment, outputfile)
342344
except IOError:

0 commit comments

Comments
 (0)