Migrate netconf-client-mdsal/api tests to JUnit5
[netconf.git] / restconf / restconf-common / src / main / java / org / opendaylight / restconf / common / errors / RestconfDocumentedException.java
1 /*
2  * Copyright (c) 2014 Brocade Communications Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.restconf.common.errors;
9
10 import static java.util.Objects.requireNonNull;
11
12 import java.util.ArrayList;
13 import java.util.Collection;
14 import java.util.List;
15 import org.eclipse.jdt.annotation.Nullable;
16 import org.opendaylight.yangtools.yang.common.ErrorTag;
17 import org.opendaylight.yangtools.yang.common.ErrorType;
18 import org.opendaylight.yangtools.yang.common.RpcError;
19 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
20 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
21
22 /**
23  * Unchecked exception to communicate error information, as defined
24  * <a href="https://www.rfc-editor.org/rfc/rfc8040#section-3.9">"errors" YANG Data Template</a>.
25  *
26  * @author Devin Avery
27  * @author Thomas Pantelis
28  */
29 @Deprecated
30 public class RestconfDocumentedException extends RuntimeException {
31     @java.io.Serial
32     private static final long serialVersionUID = 3L;
33
34     private final List<RestconfError> errors;
35
36     // FIXME: this field should be non-null
37     private final transient @Nullable EffectiveModelContext modelContext;
38
39     /**
40      * Constructs an instance with an error message. The error type defaults to APPLICATION and the error tag defaults
41      * to OPERATION_FAILED.
42      *
43      * @param message
44      *            A string which provides a plain text string describing the error.
45      */
46     public RestconfDocumentedException(final String message) {
47         this(message, ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED);
48     }
49
50     /**
51      * Constructs an instance with an error message, error type, error tag and exception cause.
52      *
53      * @param message A string which provides a plain text string describing the error.
54      * @param errorType The enumerated type indicating the layer where the error occurred.
55      * @param errorTag The enumerated tag representing a more specific error cause.
56      * @param cause The underlying exception cause.
57      */
58     public RestconfDocumentedException(final String message, final ErrorType errorType, final ErrorTag errorTag,
59                                        final Throwable cause) {
60         this(cause, new RestconfError(errorType, errorTag, message, null, cause.getMessage(), null));
61     }
62
63     /**
64      * Constructs an instance with an error message, error type, and error tag.
65      *
66      * @param message A string which provides a plain text string describing the error.
67      * @param errorType The enumerated type indicating the layer where the error occurred.
68      * @param errorTag The enumerated tag representing a more specific error cause.
69      */
70     public RestconfDocumentedException(final String message, final ErrorType errorType, final ErrorTag errorTag) {
71         this(new RestconfError(errorType, errorTag, message));
72     }
73
74     /**
75      * Constructs an instance with an error message, error type, error tag and error path.
76      *
77      * @param message A string which provides a plain text string describing the error.
78      * @param errorType The enumerated type indicating the layer where the error occurred.
79      * @param errorTag The enumerated tag representing a more specific error cause.
80      * @param errorPath The instance identifier representing error path
81      */
82     public RestconfDocumentedException(final String message, final ErrorType errorType, final ErrorTag errorTag,
83                                        final YangInstanceIdentifier errorPath) {
84         this(new RestconfError(errorType, errorTag, message, errorPath));
85     }
86
87     /**
88      * Constructs an instance with an error message and exception cause.
89      * The underlying exception is included in the error-info.
90      *
91      * @param message A string which provides a plain text string describing the error.
92      * @param cause The underlying exception cause.
93      */
94     public RestconfDocumentedException(final String message, final Throwable cause) {
95         this(cause, new RestconfError(ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED, message, null,
96             cause.getMessage(), null));
97     }
98
99     /**
100      * Constructs an instance with the given error.
101      */
102     public RestconfDocumentedException(final RestconfError error) {
103         this(null, error);
104     }
105
106     /**
107      * Constructs an instance with the given errors.
108      */
109     public RestconfDocumentedException(final String message, final Throwable cause, final List<RestconfError> errors) {
110         // FIXME: We override getMessage so supplied message is lost for any public access
111         // this was lost also in original code.
112         super(cause);
113         if (errors.isEmpty()) {
114             this.errors = List.of(new RestconfError(ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED, message));
115         } else {
116             this.errors = List.copyOf(errors);
117         }
118
119         modelContext = null;
120     }
121
122     /**
123      * Constructs an instance with the given RpcErrors.
124      */
125     public RestconfDocumentedException(final String message, final Throwable cause,
126                                        final Collection<? extends RpcError> rpcErrors) {
127         this(message, cause, convertToRestconfErrors(rpcErrors));
128     }
129
130     private static List<RestconfError> convertToRestconfErrors(final Collection<? extends RpcError> rpcErrors) {
131         if (rpcErrors == null || rpcErrors.isEmpty()) {
132             return List.of();
133         }
134
135         final var errorList = new ArrayList<RestconfError>();
136         for (var rpcError : rpcErrors) {
137             errorList.add(new RestconfError(rpcError));
138         }
139         return errorList;
140     }
141
142     public RestconfDocumentedException(final Throwable cause, final RestconfError error) {
143         super(cause);
144         errors = List.of(error);
145         modelContext = null;
146     }
147
148     public RestconfDocumentedException(final Throwable cause, final RestconfError error,
149             final EffectiveModelContext modelContext) {
150         super(cause);
151         errors = List.of(error);
152         this.modelContext = requireNonNull(modelContext);
153     }
154
155     public RestconfDocumentedException(final Throwable cause, final List<RestconfError> errors) {
156         super(cause);
157         if (errors.isEmpty()) {
158             throw new IllegalArgumentException("At least one error is required");
159         }
160         this.errors = List.copyOf(errors);
161         modelContext = null;
162     }
163
164     @Override
165     public String getMessage() {
166         return "errors: " + errors;
167     }
168
169     /**
170      * Reference to {@link EffectiveModelContext} in which this exception was generated. This method will return
171      * {@code null} if this exception was serialized or if the context is not available.
172      *
173      * @return Reference model context
174      */
175     public @Nullable EffectiveModelContext modelContext() {
176         return modelContext;
177     }
178
179     public List<RestconfError> getErrors() {
180         return errors;
181     }
182 }