Skip to content

Commit 6fc5c61

Browse files
abestofacebook-github-bot
authored andcommitted
Slightly improve error reporting
Reviewed By: AndreasBackx Differential Revision: D64753922 fbshipit-source-id: da331d0b06fdae1943ee4f219fd06c90a443c655
1 parent 8c344bc commit 6fc5c61

File tree

8 files changed

+121
-17
lines changed

8 files changed

+121
-17
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ shell-escape = "0.1"
6666
strip-ansi-escapes = "0.1"
6767
subprocess = "0.2.7"
6868
tempfile = "3.8"
69+
thiserror = "1.0"
6970
tracing = "0.1"
7071
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
7172
unicode_categories = "0.1"

selftest/complex/missing-language/missing-language.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,20 @@
22

33
```scrut
44
$ $SCRUT_BIN test --match-markdown "*.mdtest" "$TESTDIR"/missing-language.mdtest 2>&1
5-
* parse test from "*missing-language.mdtest" with markdown parser (glob)
5+
* Failed to parse test from "*missing-language.mdtest" with markdown parser (glob)
66
77
Caused by:
88
Code block starting at line 2 is missing language specifier. Use ```scrut to make this block a Scrut test, or any other language to make Scrut skip this block.
9-
* (glob?)
109
[1]
1110
```
1211

1312
# Error on EMPTY code block with no language specified
1413

1514
```scrut
1615
$ $SCRUT_BIN test --match-markdown "*.mdtest" "$TESTDIR"/missing-language-empty-block.mdtest 2>&1
17-
* parse test from "*missing-language-empty-block.mdtest" with markdown parser (glob)
16+
* Failed to parse test from "*missing-language-empty-block.mdtest" with markdown parser (glob)
1817
1918
Caused by:
2019
Code block starting at line 2 is missing language specifier. Use ```scrut to make this block a Scrut test, or any other language to make Scrut skip this block.
21-
* (glob?)
2220
[1]
2321
```

src/bin/commands/test.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
*/
77

88
use std::collections::BTreeMap;
9-
use std::fmt::Display;
109
use std::io::stdout;
1110
use std::io::IsTerminal;
1211
use std::path::Path;
@@ -47,15 +46,10 @@ use crate::utils::make_executor;
4746
use crate::utils::FileParser;
4847
use crate::utils::TestEnvironment;
4948

50-
#[derive(Debug, Clone)]
49+
#[derive(Debug, thiserror::Error)]
50+
#[error("validation failed")]
5151
pub struct ValidationFailedError;
5252

53-
impl Display for ValidationFailedError {
54-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
55-
write!(f, "validation failed")
56-
}
57-
}
58-
5953
/// Run tests from files or directories
6054
#[derive(Debug, ClapParser)]
6155
pub struct Args {

src/bin/fb_main.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
extern crate scrut;
9+
10+
mod commands;
11+
mod fb_main_common;
12+
mod utils;
13+
14+
use anyhow::Result;
15+
use cli::ExitCode;
16+
use fb_main_common::main_impl;
17+
use fb_main_common::Args;
18+
use fbinit::FacebookInit;
19+
20+
#[cli::main("scrut", error_logging)]
21+
pub fn main(fb: FacebookInit, args: Args) -> Result<ExitCode> {
22+
main_impl(fb, args)
23+
}

src/bin/fb_main_common.rs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
use anyhow::anyhow;
9+
use anyhow::Result;
10+
use clap::Parser;
11+
use cli::ExitCode;
12+
use fbinit::FacebookInit;
13+
use scrut::parsers::markdown::MarkdownParserError;
14+
use tracing::error;
15+
16+
use crate::commands::root::Commands;
17+
use crate::commands::root::GlobalParameters;
18+
use crate::commands::test::ValidationFailedError;
19+
20+
#[derive(Debug, Parser)]
21+
#[clap(
22+
about = "A testing toolkit to scrutinize CLI applications",
23+
author = "clifoundation"
24+
)]
25+
pub struct Args {
26+
#[clap(subcommand)]
27+
commands: Commands,
28+
29+
#[clap(flatten)]
30+
global: GlobalParameters,
31+
}
32+
33+
/// Implemented here because it's only used in `fb-main*.rs`, and so
34+
/// there's little point in exposing it to the OSS version.
35+
pub fn is_user_error(err: &anyhow::Error) -> bool {
36+
if let Some(MarkdownParserError::MissingLanguageSpecifier { .. }) =
37+
err.downcast_ref::<MarkdownParserError>()
38+
{
39+
return true;
40+
}
41+
false
42+
}
43+
44+
pub fn main_impl(_fb: FacebookInit, args: Args) -> Result<ExitCode> {
45+
if let Err(err) = args.commands.run() {
46+
if err.downcast_ref::<ValidationFailedError>().is_some() {
47+
return Ok(ExitCode::from(50));
48+
}
49+
if is_user_error(&err) {
50+
error!("{:?}", err);
51+
Ok(ExitCode::from(1))
52+
} else {
53+
Err(anyhow!(err))
54+
}
55+
} else {
56+
Ok(ExitCode::SUCCESS)
57+
}
58+
}

src/bin/fb_main_nodeps.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
extern crate scrut;
9+
10+
mod commands;
11+
mod fb_main_common;
12+
mod utils;
13+
14+
use anyhow::Result;
15+
use cli::ExitCode;
16+
use fb_main_common::main_impl;
17+
use fb_main_common::Args;
18+
use fbinit::FacebookInit;
19+
20+
#[cli::main("scrut", usage_logging = false)]
21+
pub fn main(fb: FacebookInit, args: Args) -> Result<ExitCode> {
22+
main_impl(fb, args)
23+
}

src/bin/utils/file_parser.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ impl<'a> FileParser<'a> {
7272
let (parser_type, parser) = self.parser(&test_file_path, cram_compat)?;
7373
let (config, testcases) = parser.parse(&test_file_content).with_context(|| {
7474
format!(
75-
"parse {} from {:?} with {} parser",
75+
"Failed to parse {} from {:?} with {} parser",
7676
name, &test_file_path, parser_type
7777
)
7878
})?;

src/parsers/markdown.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,14 @@ lazy_static! {
3030

3131
pub const DEFAULT_MARKDOWN_LANGUAGES: &[&str] = &["scrut"];
3232

33+
#[derive(Debug, thiserror::Error)]
34+
pub enum MarkdownParserError {
35+
#[error(
36+
"Code block starting at line {line} is missing language specifier. Use ```scrut to make this block a Scrut test, or any other language to make Scrut skip this block."
37+
)]
38+
MissingLanguageSpecifier { line: usize },
39+
}
40+
3341
/// A parser for Cram `.t` files, which reads [`crate::testcase::TestCase`]s
3442
/// that are encoded in the form:
3543
///
@@ -102,10 +110,9 @@ impl Parser for MarkdownParser {
102110
lines: _,
103111
} => {
104112
if language.is_empty() {
105-
anyhow::bail!(
106-
"Code block starting at line {} is missing language specifier. Use ```scrut to make this block a Scrut test, or any other language to make Scrut skip this block.",
107-
starting_line_number
108-
);
113+
anyhow::bail!(MarkdownParserError::MissingLanguageSpecifier {
114+
line: starting_line_number,
115+
});
109116
}
110117
}
111118
MarkdownToken::TestCodeBlock {

0 commit comments

Comments
 (0)