Remove unnecessary check for canceled future
[netconf.git] / restconf / restconf-nb / src / main / java / org / opendaylight / restconf / server / api / ServerException.java
1 /*
2  * Copyright (c) 2024 PANTHEON.tech, s.r.o. 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.server.api;
9
10 import static java.util.Objects.requireNonNull;
11
12 import java.io.IOException;
13 import java.io.NotSerializableException;
14 import java.io.ObjectInputStream;
15 import java.io.ObjectOutputStream;
16 import java.io.ObjectStreamException;
17 import org.eclipse.jdt.annotation.NonNullByDefault;
18 import org.eclipse.jdt.annotation.Nullable;
19 import org.opendaylight.restconf.api.ErrorMessage;
20 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
21 import org.opendaylight.restconf.common.errors.RestconfError;
22 import org.opendaylight.yangtools.yang.common.ErrorTag;
23 import org.opendaylight.yangtools.yang.common.ErrorType;
24
25 /**
26  * A server-side processing exception, reporting a single {@link ServerError}. This exception is not serializable on
27  * purpose.
28  */
29 @NonNullByDefault
30 public final class ServerException extends Exception {
31     @java.io.Serial
32     private static final long serialVersionUID = 0L;
33
34     private final ServerError error;
35
36     private ServerException(final String message, final ServerError error, final @Nullable Throwable cause) {
37         super(message, cause);
38         this.error = requireNonNull(error);
39     }
40
41     public ServerException(final String message) {
42         this(ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED, requireNonNull(message));
43     }
44
45     public ServerException(final String format, final Object @Nullable ... args) {
46         this(ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED, format, args);
47     }
48
49     public ServerException(final Throwable cause) {
50         this(ErrorType.APPLICATION, errorTagOf(cause), cause);
51     }
52
53     public ServerException(final String message, final @Nullable Throwable cause) {
54         this(ErrorType.APPLICATION, errorTagOf(cause), requireNonNull(message), cause);
55     }
56
57     public ServerException(final ErrorType type, final ErrorTag tag, final String message) {
58         this(type, tag, message, (Throwable) null);
59     }
60
61     public ServerException(final ErrorType type, final ErrorTag tag, final Throwable cause) {
62         this(cause.toString(), new ServerError(type, tag, new ErrorMessage(cause.getMessage()), null, null, null),
63             cause);
64     }
65
66     public ServerException(final ErrorType type, final ErrorTag tag, final String message,
67             final @Nullable Throwable cause) {
68         this(requireNonNull(message),
69             new ServerError(type, tag, new ErrorMessage(message), null, null, errorInfoOf(cause)), cause);
70     }
71
72     public ServerException(final ErrorType type, final ErrorTag tag, final String format,
73             final Object @Nullable ... args) {
74         this(type, tag, format.formatted(args));
75     }
76
77     public ServerException(final ErrorType type, final ErrorTag tag, final ServerErrorPath path, final String message) {
78         this(message, new ServerError(type, tag, new ErrorMessage(message), null, requireNonNull(path), null), null);
79     }
80
81     /**
82      * Return the reported {@link ServerError}.
83      *
84      * @return the reported {@link ServerError}
85      */
86     public ServerError error() {
87         return error;
88     }
89
90     @Deprecated
91     public RestconfDocumentedException toLegacy() {
92         final var message = error.message();
93         final var info = error.info();
94         final var path = error.path();
95         if (path != null) {
96             return new RestconfDocumentedException(this,
97                 new RestconfError(error.type(), error.tag(), message != null ? message.elementBody() : null,
98                     error.appTag(), info != null ? info.elementBody() : null, path.path()),
99                 path.databind().modelContext());
100         } else {
101             return new RestconfDocumentedException(this,
102                 new RestconfError(error.type(), error.tag(), message != null ? message.elementBody() : null,
103                     error.appTag(), info != null ? info.elementBody() : null, null));
104         }
105     }
106
107     @java.io.Serial
108     private void readObjectNoData() throws ObjectStreamException {
109         throw new NotSerializableException();
110     }
111
112     @java.io.Serial
113     private void readObject(final ObjectInputStream stream) throws IOException, ClassNotFoundException {
114         throw new NotSerializableException();
115     }
116
117     @java.io.Serial
118     private void writeObject(final ObjectOutputStream stream) throws IOException {
119         throw new NotSerializableException();
120     }
121
122     private static @Nullable ServerErrorInfo errorInfoOf(final @Nullable Throwable cause) {
123         if (cause != null) {
124             final var message = cause.getMessage();
125             if (message != null) {
126                 return new ServerErrorInfo(message);
127             }
128         }
129         return null;
130     }
131
132     private static ErrorTag errorTagOf(final @Nullable Throwable cause) {
133         if (cause instanceof UnsupportedOperationException) {
134             return ErrorTag.OPERATION_NOT_SUPPORTED;
135         } else if (cause instanceof IllegalArgumentException) {
136             return ErrorTag.INVALID_VALUE;
137         } else {
138             return ErrorTag.OPERATION_FAILED;
139         }
140     }
141 }