Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,13 @@ _Default is `summary`._
When configured, Gradle will use a maximum of the given number of workers. See also <<command_line_interface.adoc#sec:command_line_performance, performance command-line options>>.
_Default is number of CPU processors._

`org.gradle.logging.stacktrace=(internal,all,full)`::
Specifies whether stacktraces should be displayed as part of the build result upon an exception. See also the <<command_line_interface.adoc#sec:command_line_debugging, --stacktrace command-line option>>.
When set to `internal`, a stacktrace is present in the output only in case of internal exceptions.
When set to `all` or `full`, a stacktrace is present in the output for all exceptions and build failures.
Using `full` doesn't truncate the stacktrace, which leads to a much more verbose output.
_Default is `internal`._

The following example demonstrates usage of various properties.

.Setting properties with a gradle.properties file
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*
* Copyright 2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.gradle.launcher

import org.gradle.integtests.fixtures.AbstractIntegrationSpec

class StacktraceIntegrationTest extends AbstractIntegrationSpec {

def setup () {
buildFile << 'throw new RuntimeException("show stacktrace was " + gradle.startParameter.showStacktrace)'
settingsFile << 'rootProject.name = "stacktrace-integration-test-sample"'
executer.withStacktraceDisabled() // AbstractIntegrationSpec uses --stacktrace in the test builds by default
}

def "no stacktrace is present in the output by default"() {
when:
fails()

then:
assertCauseWithoutStacktrace('show stacktrace was INTERNAL_EXCEPTIONS')
}

def "can configure in gradle.properties file"() {
setup:
file('gradle.properties') << 'org.gradle.logging.stacktrace=full'

when:
fails()

then:
assertCauseWithStacktrace('show stacktrace was ALWAYS_FULL')
}

def "configuration is case-insensitive"() {
setup:
file('gradle.properties') << 'org.gradle.logging.stacktrace=FuLl'

when:
fails()

then:
assertCauseWithStacktrace('show stacktrace was ALWAYS_FULL')
}

def "can enable from the command line even if it's disabled in gradle.properties"() {
setup:
file('gradle.properties') << 'org.gradle.logging.stacktrace=internal'
executer.withArgument('--stacktrace')

when:
fails()

then:
assertCauseWithStacktrace('show stacktrace was ALWAYS')
}

def "emits actionable message when wrong configuration is used"() {
setup:
executer.requireDaemon().requireIsolatedDaemons()
file('gradle.properties') << 'org.gradle.logging.stacktrace=suppress'

when:
fails()

then:
assertCauseWithStacktrace(null, "Value 'suppress' given for org.gradle.logging.stacktrace Gradle property is invalid (must be one of internal, all, or full)", "java.lang.IllegalArgumentException")
}

private void assertCauseWithoutStacktrace(String cause, String description = "A problem occurred evaluating root project 'stacktrace-integration-test-sample'") {
failure.assertHasDescription(description)
failure.assertHasCause(cause)
failure.assertNotOutput('Exception is:')
}

private void assertCauseWithStacktrace(String cause, String description = "A problem occurred evaluating root project 'stacktrace-integration-test-sample'", String stackFrame = 'org.gradle.api.GradleScriptException: A problem occurred evaluating root project') {
if (cause != null) {
failure.assertHasCause(cause)
}
failure.assertHasDescription(description)
failure.assertHasErrorOutput('Exception is:')
failure.assertHasErrorOutput(stackFrame)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -142,19 +142,32 @@ private LogLevel parseLogLevel(String value) {
}

public static class StacktraceOption extends AbstractBuildOption<LoggingConfiguration, CommandLineOptionConfiguration> {
public static final String GRADLE_PROPERTY = "org.gradle.logging.stacktrace";
public static final String STACKTRACE_LONG_OPTION = "stacktrace";
public static final String STACKTRACE_SHORT_OPTION = "s";
public static final String FULL_STACKTRACE_LONG_OPTION = "full-stacktrace";
public static final String FULL_STACKTRACE_SHORT_OPTION = "S";
private static final String[] ALL_SHORT_OPTIONS = new String[]{STACKTRACE_SHORT_OPTION, FULL_STACKTRACE_SHORT_OPTION};

public StacktraceOption() {
super(null, CommandLineOptionConfiguration.create(STACKTRACE_LONG_OPTION, STACKTRACE_SHORT_OPTION, "Print out the stacktrace for all exceptions."), CommandLineOptionConfiguration.create(FULL_STACKTRACE_LONG_OPTION, FULL_STACKTRACE_SHORT_OPTION, "Print out the full (very verbose) stacktrace for all exceptions."));
super(GRADLE_PROPERTY, CommandLineOptionConfiguration.create(STACKTRACE_LONG_OPTION, STACKTRACE_SHORT_OPTION, "Print out the stacktrace for all exceptions."), CommandLineOptionConfiguration.create(FULL_STACKTRACE_LONG_OPTION, FULL_STACKTRACE_SHORT_OPTION, "Print out the full (very verbose) stacktrace for all exceptions."));
}

@Override
public void applyFromProperty(Map<String, String> properties, LoggingConfiguration settings) {
// not supported
String value = properties.get(gradleProperty);

if (value != null) {
if (value.equalsIgnoreCase("internal")) {
settings.setShowStacktrace(ShowStacktrace.INTERNAL_EXCEPTIONS);
} else if (value.equalsIgnoreCase("all")) {
settings.setShowStacktrace(ShowStacktrace.ALWAYS);
} else if (value.equalsIgnoreCase("full")) {
settings.setShowStacktrace(ShowStacktrace.ALWAYS_FULL);
} else {
Origin.forGradleProperty(GRADLE_PROPERTY).handleInvalidValue(value, "must be one of internal, all, or full");
}
}
}

@Override
Expand Down