Skip to content

Commit e9298c2

Browse files
committed
Fix #32571: improve SpEL error-reporting
1 parent e8e79cf commit e9298c2

5 files changed

Lines changed: 120 additions & 1 deletion

File tree

src/main/java/eu/openanalytics/containerproxy/backend/dispatcher/proxysharing/ProxySharingScaler.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@
5454
import eu.openanalytics.containerproxy.service.leader.ILeaderService;
5555
import eu.openanalytics.containerproxy.spec.expression.SpecExpressionContext;
5656
import eu.openanalytics.containerproxy.spec.expression.SpecExpressionResolver;
57+
import eu.openanalytics.containerproxy.spec.expression.SpelContextObjectNotAvailableException;
58+
import eu.openanalytics.containerproxy.spec.expression.SpelException;
5759
import eu.openanalytics.containerproxy.spec.expression.SpelField;
5860
import eu.openanalytics.containerproxy.util.ExecutorServiceFactory;
5961
import eu.openanalytics.containerproxy.util.MathUtil;
@@ -417,6 +419,10 @@ private Runnable createDelegateProxyJob(DelegateProxy originalDelegateProxy) {
417419
applicationEventPublisher.publishEvent(new SeatAvailableEvent(proxySpec.getId(), intendedProxyId));
418420
}
419421
}
422+
} catch (SpelContextObjectNotAvailableException | SpelException ex) {
423+
// remove seats and other data
424+
globalEventLoop.schedule(() -> markDelegateProxyForRemoval(id));
425+
logger.error("Failed to start DelegateProxy, problem while resolving SpEL expressions. You can only use the objects 'containerSpec', 'proxySpec' and 'proxy' when using pre-initialized containers. Cause: " + ex.getMessage());
420426
} catch (ProxyFailedToStartException t) {
421427
logError(originalDelegateProxy, t, "Failed to start DelegateProxy");
422428
try {

src/main/java/eu/openanalytics/containerproxy/spec/expression/SpecExpressionContext.java

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
import java.util.List;
4141

4242
@Value
43-
@EqualsAndHashCode()
43+
@EqualsAndHashCode(doNotUseGetters = true)
4444
@Builder(toBuilder = true)
4545
@AllArgsConstructor
4646
public class SpecExpressionContext {
@@ -149,4 +149,73 @@ public SpecExpressionContext copy(Object... objects) {
149149
return create(toBuilder(), objects);
150150
}
151151

152+
public ProxySpec getProxySpec() {
153+
if (proxySpec == null) {
154+
throw new SpelContextObjectNotAvailableException("proxySpec");
155+
}
156+
return proxySpec;
157+
}
158+
159+
public ContainerSpec getContainerSpec() {
160+
if (containerSpec == null) {
161+
throw new SpelContextObjectNotAvailableException("containerSpec");
162+
}
163+
return containerSpec;
164+
}
165+
166+
public Proxy getProxy() {
167+
if (proxy == null) {
168+
throw new SpelContextObjectNotAvailableException("proxy");
169+
}
170+
return proxy;
171+
}
172+
173+
public OpenIDAuthenticationBackend.CustomNameOidcUser getOidcUser() {
174+
if (oidcUser == null) {
175+
throw new SpelContextObjectNotAvailableException("oidcUser");
176+
}
177+
return oidcUser;
178+
}
179+
180+
public ResponseAuthenticationConverter.Saml2AuthenticatedPrincipal getSamlCredential() {
181+
if (samlCredential == null) {
182+
throw new SpelContextObjectNotAvailableException("samlCredential");
183+
}
184+
return samlCredential;
185+
}
186+
187+
public LdapUserDetails getLdapUser() {
188+
if (ldapUser == null) {
189+
throw new SpelContextObjectNotAvailableException("ldapUser");
190+
}
191+
return ldapUser;
192+
}
193+
194+
public WebServiceAuthenticationBackend.WebServiceUser getWebServiceUser() {
195+
if (oidcUser == null) {
196+
throw new SpelContextObjectNotAvailableException("webServiceUser");
197+
}
198+
return webServiceUser;
199+
}
200+
201+
public List<String> getGroups() {
202+
if (groups == null) {
203+
throw new SpelContextObjectNotAvailableException("groups");
204+
}
205+
return groups;
206+
}
207+
208+
public String getUserId() {
209+
if (userId == null) {
210+
throw new SpelContextObjectNotAvailableException("userId");
211+
}
212+
return userId;
213+
}
214+
215+
public JsonNode getJson() {
216+
if (json == null) {
217+
throw new SpelContextObjectNotAvailableException("json");
218+
}
219+
return json;
220+
}
152221
}

src/main/java/eu/openanalytics/containerproxy/spec/expression/SpecExpressionResolver.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
import com.fasterxml.jackson.databind.JsonNode;
2424
import com.fasterxml.jackson.databind.node.ArrayNode;
25+
import com.google.common.base.Throwables;
2526
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
2627
import org.springframework.context.ApplicationContext;
2728
import org.springframework.context.ConfigurableApplicationContext;
@@ -106,7 +107,13 @@ public <T> T evaluate(String expression, SpecExpressionContext context, Class<T>
106107
}
107108

108109
return expr.getValue(sec, resType);
110+
} catch (SpelContextObjectNotAvailableException ex) {
111+
throw new SpelException(ex, expression);
109112
} catch (ExpressionException ex) {
113+
Throwable rootCause = Throwables.getRootCause(ex);
114+
if (rootCause instanceof SpelContextObjectNotAvailableException contextObjectNotAvailableException) {
115+
throw new SpelContextObjectNotAvailableException(contextObjectNotAvailableException, expression);
116+
}
110117
throw new SpelException(ex, expression);
111118
} catch (Throwable ex) {
112119
throw new SpelException(ex, expression);
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/**
2+
* ContainerProxy
3+
*
4+
* Copyright (C) 2016-2024 Open Analytics
5+
*
6+
* ===========================================================================
7+
*
8+
* This program is free software: you can redistribute it and/or modify
9+
* it under the terms of the Apache License as published by
10+
* The Apache Software Foundation, either version 2 of the License, or
11+
* (at your option) any later version.
12+
*
13+
* This program is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
* Apache License for more details.
17+
*
18+
* You should have received a copy of the Apache License
19+
* along with this program. If not, see <http://www.apache.org/licenses/>
20+
*/
21+
package eu.openanalytics.containerproxy.spec.expression;
22+
23+
public class SpelContextObjectNotAvailableException extends RuntimeException {
24+
25+
public SpelContextObjectNotAvailableException(String objectName) {
26+
super("Object \"" + objectName + "\" not available in SpelContext.");
27+
}
28+
29+
public SpelContextObjectNotAvailableException(SpelContextObjectNotAvailableException ex, String expression) {
30+
super("Error while resolving expression: \"" + expression + "\", error: " + ex.getMessage());
31+
}
32+
33+
}

src/main/java/eu/openanalytics/containerproxy/spec/expression/SpelException.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ public SpelException(ExpressionException cause, String originalExpression) {
2828
super("Error while resolving expression: \"" + originalExpression + "\", error: " + cause.getMessage());
2929
}
3030

31+
public SpelException(SpelContextObjectNotAvailableException cause, String originalExpression) {
32+
super("Error while resolving expression: \"" + originalExpression + "\", error: " + cause.getMessage());
33+
}
34+
3135
public SpelException(Throwable cause, String originalExpression) {
3236
super("Error while resolving expression: \"" + originalExpression + "\", error: " + cause.getMessage(), cause);
3337
}

0 commit comments

Comments
 (0)