1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19 package org.eclipse.aether.collection;
20
21 import org.eclipse.aether.RepositoryException;
22
23 /**
24 * Thrown in case of bad artifact descriptors, version ranges or other issues encountered during calculation of the
25 * dependency graph.
26 */
27 public class DependencyCollectionException extends RepositoryException {
28
29 private final transient CollectResult result;
30
31 /**
32 * Creates a new exception with the specified result.
33 * Cause will be first selected exception from result, if applicable. All exceptions are added as suppressed as well.
34 *
35 * @param result The collection result at the point the exception occurred, may be {@code null}.
36 */
37 public DependencyCollectionException(CollectResult result) {
38 super("Failed to collect dependencies for " + getSource(result), getFirstCause(result));
39 if (result != null) {
40 result.getExceptions().forEach(this::addSuppressed);
41 }
42 this.result = result;
43 }
44
45 /**
46 * Creates a new exception with the specified result and detail message.
47 * Cause will be first selected exception from result, if applicable. All exceptions are added as suppressed as well.
48 *
49 * @param result The collection result at the point the exception occurred, may be {@code null}.
50 * @param message The detail message, may be {@code null}.
51 */
52 public DependencyCollectionException(CollectResult result, String message) {
53 super(message, getFirstCause(result));
54 if (result != null) {
55 result.getExceptions().forEach(this::addSuppressed);
56 }
57 this.result = result;
58 }
59
60 /**
61 * Creates a new exception with the specified result, detail message and cause.
62 * All exceptions are added as suppressed as well.
63 *
64 * @param result The collection result at the point the exception occurred, may be {@code null}.
65 * @param message The detail message, may be {@code null}.
66 * @param cause The exception that caused this one, may be {@code null}.
67 */
68 public DependencyCollectionException(CollectResult result, String message, Throwable cause) {
69 super(message, cause);
70 if (result != null) {
71 result.getExceptions().forEach(this::addSuppressed);
72 }
73 this.result = result;
74 }
75
76 /**
77 * Gets the collection result at the point the exception occurred. Despite being incomplete, callers might want to
78 * use this result to fail gracefully and continue their operation with whatever interim data has been gathered.
79 *
80 * @return The collection result or {@code null} if unknown.
81 */
82 public CollectResult getResult() {
83 return result;
84 }
85
86 private static String getSource(CollectResult result) {
87 if (result == null) {
88 return "";
89 }
90
91 CollectRequest request = result.getRequest();
92 if (request.getRoot() != null) {
93 return request.getRoot().toString();
94 }
95 if (request.getRootArtifact() != null) {
96 return request.getRootArtifact().toString();
97 }
98
99 return request.getDependencies().toString();
100 }
101
102 private static Throwable getFirstCause(CollectResult result) {
103 Throwable cause = null;
104 if (result != null && !result.getExceptions().isEmpty()) {
105 cause = result.getExceptions().get(0);
106 }
107 return cause;
108 }
109 }