import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor;
import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangInferencePipeline;
import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Throwables;
import com.google.common.collect.Maps;
import java.io.Closeable;
import java.io.File;
// MojoExecutionException is thrown since execution cannot continue
} catch (Exception e) {
LOG.error("{} Unable to parse {} files from {}", LOG_PREFIX, Util.YANG_SUFFIX, yangFilesRootDir, e);
+ Throwable rootCause = Throwables.getRootCause(e);
throw new MojoExecutionException(LOG_PREFIX + " Unable to parse " + Util.YANG_SUFFIX + " files from " +
- yangFilesRootDir, e);
+ yangFilesRootDir, rootCause);
}
}
sc = Optional.of(f.checkedGet());
break;
} catch (SchemaResolutionException e) {
- LOG.debug("Failed to fully assemble schema context for {}", sources, e);
+ LOG.info("Failed to fully assemble schema context for {}", sources, e);
sources = e.getResolvedSources();
}
}
import org.opendaylight.yangtools.yang.parser.spi.validation.ValidationBundlesNamespace.ValidationBundleType;
import org.opendaylight.yangtools.yang.parser.stmt.reactor.SourceSpecificContext.PhaseCompletionProgress;
import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveSchemaContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBehaviour.Registry {
+ private static final Logger LOG = LoggerFactory.getLogger(BuildGlobalContext.class);
private static final List<ModelProcessingPhase> PHASE_EXECUTION_ORDER = ImmutableList.<ModelProcessingPhase>builder()
.add(ModelProcessingPhase.SOURCE_LINKAGE)
@SuppressWarnings({"unchecked", "rawtypes"})
private <K, V, N extends IdentifierNamespace<K, V>> NamespaceBehaviourWithListeners<K, V, N> createNamespaceContext(
- NamespaceBehaviour<K, V, N> potentialRaw) {
+ final NamespaceBehaviour<K, V, N> potentialRaw) {
if (potentialRaw instanceof DerivedNamespaceBehaviour) {
VirtualNamespaceContext derivedContext =
new VirtualNamespaceContext((DerivedNamespaceBehaviour) potentialRaw);
private SomeModifiersUnresolvedException addSourceExceptions(final SomeModifiersUnresolvedException buildFailure,
final List<SourceSpecificContext> sourcesToProgress) {
- for(SourceSpecificContext failedSource : sourcesToProgress) {
- SourceException sourceEx = failedSource.failModifiers(currentPhase);
- buildFailure.addSuppressed(sourceEx);
+ boolean addedCause = false;
+ for (SourceSpecificContext failedSource : sourcesToProgress) {
+ final SourceException sourceEx = failedSource.failModifiers(currentPhase);
+
+ // Workaround for broken logging implementations which ignore suppressed exceptions
+ Throwable cause = sourceEx.getCause() != null ? sourceEx.getCause() : sourceEx;
+ if (LOG.isDebugEnabled()) {
+ LOG.error("Failed to parse YANG from source {}", failedSource, sourceEx);
+ } else {
+ LOG.error("Failed to parse YANG from source {}: {}", failedSource, cause.getMessage());
+ }
+
+ final Throwable[] suppressed = sourceEx.getSuppressed();
+ if (suppressed.length > 0) {
+ LOG.error("{} additional errors reported:", suppressed.length);
+
+ int i = 1;
+ for (Throwable t : suppressed) {
+ // FIXME: this should be configured in the appender, really
+ if (LOG.isDebugEnabled()) {
+ LOG.error("Error {}: {}", i, t.getMessage(), t);
+ } else {
+ LOG.error("Error {}: {}", i, t.getMessage());
+ }
+
+ i++;
+ }
+ }
+
+ if(!addedCause) {
+ addedCause = true;
+ buildFailure.initCause(sourceEx);
+ } else {
+ buildFailure.addSuppressed(sourceEx);
+ }
}
return buildFailure;
}
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import java.util.Objects;
import javax.annotation.Nullable;
}
SourceException failModifiers(final ModelProcessingPhase identifier) {
- InferenceException sourceEx = new InferenceException("Fail to infer source relationships", root.getStatementSourceReference());
-
-
+ final List<SourceException> exceptions = new ArrayList<>();
for (ModifierImpl mod : modifiers.get(identifier)) {
try {
mod.failModifier();
} catch (SourceException e) {
- sourceEx.addSuppressed(e);
+ exceptions.add(e);
}
}
- return sourceEx;
+
+ final String message = String.format("Yang model processing phase %s failed", identifier);
+ if (exceptions.isEmpty()) {
+ return new InferenceException(message, root.getStatementSourceReference());
+ }
+
+ final InferenceException e = new InferenceException(message, root.getStatementSourceReference(),
+ exceptions.get(0));
+ final Iterator<SourceException> it = exceptions.listIterator(1);
+ while (it.hasNext()) {
+ e.addSuppressed(it.next());
+ }
+
+ return e;
}
void loadStatements() throws SourceException {
return statementContext;
}
+ @Override
+ public String toString() {
+ return sourceName;
+ }
+
// public InputStream getSourceStream() {
// return sourceStream;
// }
import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
import org.opendaylight.yangtools.yang.parser.util.YangParseException;
import org.opendaylight.yangtools.yang.parser.util.YangValidationException;
+import com.google.common.base.Throwables;
public class YangParserNegativeTest {
fail("SomeModifiersUnresolvedException should be thrown");
}
} catch (SomeModifiersUnresolvedException e) {
- final Throwable suppressed2levelsDown = e.getSuppressed()[0].getSuppressed()[0];
- assertTrue(suppressed2levelsDown instanceof InferenceException);
- assertTrue(suppressed2levelsDown.getMessage().startsWith("Imported module"));
- assertTrue(suppressed2levelsDown.getMessage().endsWith("was not found."));
+ Throwable rootCause = Throwables.getRootCause(e);
+ assertTrue(rootCause instanceof InferenceException);
+ assertTrue(rootCause.getMessage().startsWith("Imported module"));
+ assertTrue(rootCause.getMessage().endsWith("was not found."));
}
}
}
}
} catch (SomeModifiersUnresolvedException e) {
- final Throwable suppressed2levelsDown = e.getSuppressed()[0].getSuppressed()[0];
- assertTrue(suppressed2levelsDown instanceof InferenceException);
+ final Throwable rootCause = Throwables.getRootCause(e);
+ assertTrue(rootCause instanceof InferenceException);
assertEquals(
"Augment target not found: Absolute{path=[(urn:simple.container.demo?revision=1970-01-01)unknown]}",
- suppressed2levelsDown.getMessage());
+ rootCause.getMessage());
}
}