Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a config option to limit the max amount of characters for a value shown in error messages #110

Merged
merged 11 commits into from
Feb 18, 2025
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

1. Slow uniqueness check (> 2hrs for 100k samples) made 400x faster by switching from `findAll` to a `subMap` for isolating the required unique fields.
2. `patternProperties` now has greater support, with no warnings about invalid parameters which actually match a pattern
3. Added a new configuration option: `validation.maxValueLength` which sets the maximum length that a value in an error message can be. The default is set to 150 characters.

## Changes

Expand Down
12 changes: 12 additions & 0 deletions docs/configuration/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,18 @@ This option does exactly the same as `validation.ignoreParams`, but provides pip
validation.defaultIgnoreParams = ["param1", "param2"] // default: []
```

## maxValueLength

Configure the maximum characters of a value that may be shown in an error message. It takes a whole number above or equal to `0`. A value will be truncated when it goes over the maximum amount of characters. See the below example where the limit is to 20 characters:

```
* --test (abcdefghij...qrstuvwxyz): Value is [string] but should be [integer]
```

```groovy
validation.maxValueLength = 100 // default: 150
```

## help

The `validation.help` config scope can be used to configure the creation of the help message.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,20 @@ class ValidationConfig {
final public Boolean failUnrecognisedHeaders
final public String parametersSchema
final public Boolean showHiddenParams
final public Integer maxValueLength
final public HelpConfig help
final public SummaryConfig summary

final public List<String> ignoreParams

ValidationConfig(Map map, Map params){
def config = map ?: Collections.emptyMap()
lenientMode = config.lenientMode ?: false
monochromeLogs = config.monochromeLogs ?: false
failUnrecognisedParams = config.failUnrecognisedParams ?: false
failUnrecognisedHeaders = config.failUnrecognisedHeaders ?: false
showHiddenParams = config.showHiddenParams ?: false
lenientMode = config.lenientMode ?: false
monochromeLogs = config.monochromeLogs ?: false
failUnrecognisedParams = config.failUnrecognisedParams ?: false
failUnrecognisedHeaders = config.failUnrecognisedHeaders ?: false
showHiddenParams = config.showHiddenParams ?: false
maxValueLength = config.maxValueLength && config.maxValueLength >= 0 ? config.maxValueLength : 150
if(config.containsKey("showHiddenParams")) {
log.warn("configuration option `validation.showHiddenParams` is deprecated, please use `validation.help.showHidden` or the `--showHidden` parameter instead")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ public class JsonSchemaValidator {

def String instanceLocation = error.getInstanceLocation()
def String value = getValueFromJsonPointer(instanceLocation, rawJson)
if(value.size() > config.maxValueLength) {
value = "${value[0..(config.maxValueLength/2-1)]}...${value[-config.maxValueLength/2..-1]}" as String
}

// Get the custom errorMessage if there is one and the validation errors are not about the content of the file
def String schemaLocation = error.getSchemaLocation().replaceFirst(/^[^#]+/, "")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1409,4 +1409,30 @@ class ValidateParametersTest extends Dsl2Spec{
!stdout
}

def 'should truncate long values in errors' () {
given:
def schema = Path.of('src/testResources/nextflow_schema.json').toAbsolutePath().toString()
def SCRIPT = """
params.input = 'src/testResources/wrong_samplesheet_with_a_super_long_name.and_a_weird_extension'
params.outdir = 'src/testResources/testDir'
include { validateParameters } from 'plugin/nf-schema'

validateParameters(parameters_schema: '$schema')
"""

when:
def config = ["validation": [
"maxValueLength": 20
]]
def result = new MockScriptRunner(config).setScript(SCRIPT).execute()
def stdout = capture
.toString()
.readLines()
.findResults {it.contains('WARN nextflow.validation.SchemaValidator') || it.startsWith('* --') ? it : null }

then:
def error = thrown(SchemaValidationException)
error.message.contains("* --input (src/testRe..._extension): \"src/testResources/wrong_samplesheet_with_a_super_long_name.and_a_weird_extension\" does not match regular expression [^\\S+\\.(csv|tsv|yaml|json)\$]")
!stdout
}
}