This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new 43e80d0adb64 camel-core - Add throwExceptrion function to simple
43e80d0adb64 is described below
commit 43e80d0adb64dc4b086c6c8060918ae134208c8f
Author: Claus Ibsen <[email protected]>
AuthorDate: Sat Jan 24 18:13:28 2026 +0100
camel-core - Add throwExceptrion function to simple
---
.../org/apache/camel/catalog/languages/simple.json | 17 +++----
.../language/csimple/joor/OriginalSimpleTest.java | 24 ++++++++++
.../org/apache/camel/language/simple/simple.json | 17 +++----
.../modules/languages/pages/simple-language.adoc | 1 +
.../camel/language/csimple/CSimpleHelper.java | 17 +++++++
.../camel/language/simple/SimpleConstants.java | 4 ++
.../language/simple/SimpleExpressionBuilder.java | 50 ++++++++++++++++++++
.../simple/ast/SimpleFunctionExpression.java | 55 ++++++++++++++++++++++
.../apache/camel/language/simple/SimpleTest.java | 25 ++++++++++
9 files changed, 194 insertions(+), 16 deletions(-)
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/simple.json
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/simple.json
index 890b39760010..43afc5b8cc86 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/simple.json
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/simple.json
@@ -116,13 +116,14 @@
"sys.name": { "index": 89, "kind": "function", "displayName": "JVM System
Property", "group": "function", "label": "function", "required": false,
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote":
"", "autowired": false, "secret": false, "description": "The JVM system
property with the given name", "ognl": false, "suffix": "}" },
"threadId": { "index": 90, "kind": "function", "displayName": "Thread Id",
"group": "function", "label": "function", "required": false, "javaType":
"long", "prefix": "${", "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "description": "Returns the id of the
current thread. Can be used for logging.", "ognl": false, "suffix": "}" },
"threadName": { "index": 91, "kind": "function", "displayName": "Thread
Name", "group": "function", "label": "function", "required": false, "javaType":
"String", "prefix": "${", "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "description": "Returns the name of the
current thread. Can be used for logging.", "ognl": false, "suffix": "}" },
- "trim(exp)": { "index": 92, "kind": "function", "displayName": "Trim",
"group": "function", "label": "function", "required": false, "javaType":
"String", "prefix": "${", "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "description": "The trim function trims
the message body (or expression) by removing all leading and trailing white
spaces.", "ognl": false, "suffix": "}" },
- "type:name.field": { "index": 93, "kind": "function", "displayName": "Java
Field Value", "group": "function", "label": "function", "required": false,
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote":
"", "autowired": false, "secret": false, "description": "To refer to a type or
field by its classname. To refer to a field, you can append .FIELD_NAME. For
example, you can refer to the constant field from Exchange as:
`org.apache.camel.Exchange.FILE_NAME`", " [...]
- "uppercase(exp)": { "index": 94, "kind": "function", "displayName":
"Uppercase", "group": "function", "label": "function", "required": false,
"javaType": "String", "prefix": "${", "deprecated": false, "deprecationNote":
"", "autowired": false, "secret": false, "description": "Uppercases the message
body (or expression)", "ognl": false, "suffix": "}" },
- "uuid(type)": { "index": 95, "kind": "function", "displayName": "Generate
UUID", "group": "function", "label": "function", "required": false, "javaType":
"String", "prefix": "${", "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "description": "Returns a UUID using the
Camel `UuidGenerator`. You can choose between `default`, `classic`, `short` and
`simple` as the type. If no type is given, the default is used. It is also
possible to use a custom `UuidG [...]
- "variable.name": { "index": 96, "kind": "function", "displayName":
"Variable", "group": "function", "label": "function", "required": false,
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote":
"", "autowired": false, "secret": false, "description": "The variable with the
given name", "ognl": true, "suffix": "}" },
- "variableAs(key,type)": { "index": 97, "kind": "function", "displayName":
"Variable As", "group": "function", "label": "function", "required": false,
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote":
"", "autowired": false, "secret": false, "description": "Converts the variable
to the given type (classname).", "ognl": false, "suffix": "}" },
- "variables": { "index": 98, "kind": "function", "displayName":
"Variables", "group": "function", "label": "function", "required": false,
"javaType": "java.util.Map", "prefix": "${", "deprecated": false,
"deprecationNote": "", "autowired": false, "secret": false, "description":
"Returns all the variables from the current Exchange in a Map", "ognl": false,
"suffix": "}" },
- "xpath(input,exp)": { "index": 99, "kind": "function", "displayName":
"XPath", "group": "function", "label": "function", "required": false,
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote":
"", "autowired": false, "secret": false, "description": "When working with XML
data, then this allows using the XPath language, for example, to extract data
from the message body (in XML format). This requires having camel-xpath JAR on
the classpath. For input (optional [...]
+ "throwException(type,msg)": { "index": 92, "kind": "function",
"displayName": "Throw Exception", "group": "function", "label": "function",
"required": false, "javaType": "java.lang.Exception", "prefix": "${",
"deprecated": false, "deprecationNote": "", "autowired": false, "secret":
false, "description": "Deliberately throws an error. Uses
IllegalArgumentException by default if no type is specified (use fully
qualified classname).", "ognl": false, "suffix": "}" },
+ "trim(exp)": { "index": 93, "kind": "function", "displayName": "Trim",
"group": "function", "label": "function", "required": false, "javaType":
"String", "prefix": "${", "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "description": "The trim function trims
the message body (or expression) by removing all leading and trailing white
spaces.", "ognl": false, "suffix": "}" },
+ "type:name.field": { "index": 94, "kind": "function", "displayName": "Java
Field Value", "group": "function", "label": "function", "required": false,
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote":
"", "autowired": false, "secret": false, "description": "To refer to a type or
field by its classname. To refer to a field, you can append .FIELD_NAME. For
example, you can refer to the constant field from Exchange as:
`org.apache.camel.Exchange.FILE_NAME`", " [...]
+ "uppercase(exp)": { "index": 95, "kind": "function", "displayName":
"Uppercase", "group": "function", "label": "function", "required": false,
"javaType": "String", "prefix": "${", "deprecated": false, "deprecationNote":
"", "autowired": false, "secret": false, "description": "Uppercases the message
body (or expression)", "ognl": false, "suffix": "}" },
+ "uuid(type)": { "index": 96, "kind": "function", "displayName": "Generate
UUID", "group": "function", "label": "function", "required": false, "javaType":
"String", "prefix": "${", "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "description": "Returns a UUID using the
Camel `UuidGenerator`. You can choose between `default`, `classic`, `short` and
`simple` as the type. If no type is given, the default is used. It is also
possible to use a custom `UuidG [...]
+ "variable.name": { "index": 97, "kind": "function", "displayName":
"Variable", "group": "function", "label": "function", "required": false,
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote":
"", "autowired": false, "secret": false, "description": "The variable with the
given name", "ognl": true, "suffix": "}" },
+ "variableAs(key,type)": { "index": 98, "kind": "function", "displayName":
"Variable As", "group": "function", "label": "function", "required": false,
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote":
"", "autowired": false, "secret": false, "description": "Converts the variable
to the given type (classname).", "ognl": false, "suffix": "}" },
+ "variables": { "index": 99, "kind": "function", "displayName":
"Variables", "group": "function", "label": "function", "required": false,
"javaType": "java.util.Map", "prefix": "${", "deprecated": false,
"deprecationNote": "", "autowired": false, "secret": false, "description":
"Returns all the variables from the current Exchange in a Map", "ognl": false,
"suffix": "}" },
+ "xpath(input,exp)": { "index": 100, "kind": "function", "displayName":
"XPath", "group": "function", "label": "function", "required": false,
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote":
"", "autowired": false, "secret": false, "description": "When working with XML
data, then this allows using the XPath language, for example, to extract data
from the message body (in XML format). This requires having camel-xpath JAR on
the classpath. For input (optiona [...]
}
}
diff --git
a/components/camel-csimple-joor/src/test/java/org/apache/camel/language/csimple/joor/OriginalSimpleTest.java
b/components/camel-csimple-joor/src/test/java/org/apache/camel/language/csimple/joor/OriginalSimpleTest.java
index f283276079f2..97e88e3f650c 100644
---
a/components/camel-csimple-joor/src/test/java/org/apache/camel/language/csimple/joor/OriginalSimpleTest.java
+++
b/components/camel-csimple-joor/src/test/java/org/apache/camel/language/csimple/joor/OriginalSimpleTest.java
@@ -17,6 +17,7 @@
package org.apache.camel.language.csimple.joor;
import java.io.File;
+import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.ArrayList;
@@ -3285,6 +3286,29 @@ public class OriginalSimpleTest extends
LanguageTestSupport {
assertTrue(expression.evaluate(exchange, Boolean.class));
}
+ @Test
+ public void testThrowException() {
+ try {
+ Expression expression =
context.resolveLanguage("csimple").createExpression("${throwException('Forced
error')}");
+ expression.evaluate(exchange, Object.class);
+ fail();
+ } catch (Exception e) {
+ assertIsInstanceOf(IllegalArgumentException.class,
e.getCause().getCause());
+ assertEquals("Forced error", e.getCause().getCause().getMessage());
+ }
+
+ try {
+ Expression expression
+ = context.resolveLanguage("csimple")
+ .createExpression("${throwException('Some IO
error','java.io.IOException')}");
+ expression.evaluate(exchange, Object.class);
+ fail();
+ } catch (Exception e) {
+ assertIsInstanceOf(IOException.class,
e.getCause().getCause().getCause());
+ assertEquals("Some IO error",
e.getCause().getCause().getCause().getMessage());
+ }
+ }
+
@Override
protected String getLanguageName() {
return "csimple";
diff --git
a/core/camel-core-languages/src/generated/resources/META-INF/org/apache/camel/language/simple/simple.json
b/core/camel-core-languages/src/generated/resources/META-INF/org/apache/camel/language/simple/simple.json
index 890b39760010..43afc5b8cc86 100644
---
a/core/camel-core-languages/src/generated/resources/META-INF/org/apache/camel/language/simple/simple.json
+++
b/core/camel-core-languages/src/generated/resources/META-INF/org/apache/camel/language/simple/simple.json
@@ -116,13 +116,14 @@
"sys.name": { "index": 89, "kind": "function", "displayName": "JVM System
Property", "group": "function", "label": "function", "required": false,
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote":
"", "autowired": false, "secret": false, "description": "The JVM system
property with the given name", "ognl": false, "suffix": "}" },
"threadId": { "index": 90, "kind": "function", "displayName": "Thread Id",
"group": "function", "label": "function", "required": false, "javaType":
"long", "prefix": "${", "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "description": "Returns the id of the
current thread. Can be used for logging.", "ognl": false, "suffix": "}" },
"threadName": { "index": 91, "kind": "function", "displayName": "Thread
Name", "group": "function", "label": "function", "required": false, "javaType":
"String", "prefix": "${", "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "description": "Returns the name of the
current thread. Can be used for logging.", "ognl": false, "suffix": "}" },
- "trim(exp)": { "index": 92, "kind": "function", "displayName": "Trim",
"group": "function", "label": "function", "required": false, "javaType":
"String", "prefix": "${", "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "description": "The trim function trims
the message body (or expression) by removing all leading and trailing white
spaces.", "ognl": false, "suffix": "}" },
- "type:name.field": { "index": 93, "kind": "function", "displayName": "Java
Field Value", "group": "function", "label": "function", "required": false,
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote":
"", "autowired": false, "secret": false, "description": "To refer to a type or
field by its classname. To refer to a field, you can append .FIELD_NAME. For
example, you can refer to the constant field from Exchange as:
`org.apache.camel.Exchange.FILE_NAME`", " [...]
- "uppercase(exp)": { "index": 94, "kind": "function", "displayName":
"Uppercase", "group": "function", "label": "function", "required": false,
"javaType": "String", "prefix": "${", "deprecated": false, "deprecationNote":
"", "autowired": false, "secret": false, "description": "Uppercases the message
body (or expression)", "ognl": false, "suffix": "}" },
- "uuid(type)": { "index": 95, "kind": "function", "displayName": "Generate
UUID", "group": "function", "label": "function", "required": false, "javaType":
"String", "prefix": "${", "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "description": "Returns a UUID using the
Camel `UuidGenerator`. You can choose between `default`, `classic`, `short` and
`simple` as the type. If no type is given, the default is used. It is also
possible to use a custom `UuidG [...]
- "variable.name": { "index": 96, "kind": "function", "displayName":
"Variable", "group": "function", "label": "function", "required": false,
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote":
"", "autowired": false, "secret": false, "description": "The variable with the
given name", "ognl": true, "suffix": "}" },
- "variableAs(key,type)": { "index": 97, "kind": "function", "displayName":
"Variable As", "group": "function", "label": "function", "required": false,
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote":
"", "autowired": false, "secret": false, "description": "Converts the variable
to the given type (classname).", "ognl": false, "suffix": "}" },
- "variables": { "index": 98, "kind": "function", "displayName":
"Variables", "group": "function", "label": "function", "required": false,
"javaType": "java.util.Map", "prefix": "${", "deprecated": false,
"deprecationNote": "", "autowired": false, "secret": false, "description":
"Returns all the variables from the current Exchange in a Map", "ognl": false,
"suffix": "}" },
- "xpath(input,exp)": { "index": 99, "kind": "function", "displayName":
"XPath", "group": "function", "label": "function", "required": false,
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote":
"", "autowired": false, "secret": false, "description": "When working with XML
data, then this allows using the XPath language, for example, to extract data
from the message body (in XML format). This requires having camel-xpath JAR on
the classpath. For input (optional [...]
+ "throwException(type,msg)": { "index": 92, "kind": "function",
"displayName": "Throw Exception", "group": "function", "label": "function",
"required": false, "javaType": "java.lang.Exception", "prefix": "${",
"deprecated": false, "deprecationNote": "", "autowired": false, "secret":
false, "description": "Deliberately throws an error. Uses
IllegalArgumentException by default if no type is specified (use fully
qualified classname).", "ognl": false, "suffix": "}" },
+ "trim(exp)": { "index": 93, "kind": "function", "displayName": "Trim",
"group": "function", "label": "function", "required": false, "javaType":
"String", "prefix": "${", "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "description": "The trim function trims
the message body (or expression) by removing all leading and trailing white
spaces.", "ognl": false, "suffix": "}" },
+ "type:name.field": { "index": 94, "kind": "function", "displayName": "Java
Field Value", "group": "function", "label": "function", "required": false,
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote":
"", "autowired": false, "secret": false, "description": "To refer to a type or
field by its classname. To refer to a field, you can append .FIELD_NAME. For
example, you can refer to the constant field from Exchange as:
`org.apache.camel.Exchange.FILE_NAME`", " [...]
+ "uppercase(exp)": { "index": 95, "kind": "function", "displayName":
"Uppercase", "group": "function", "label": "function", "required": false,
"javaType": "String", "prefix": "${", "deprecated": false, "deprecationNote":
"", "autowired": false, "secret": false, "description": "Uppercases the message
body (or expression)", "ognl": false, "suffix": "}" },
+ "uuid(type)": { "index": 96, "kind": "function", "displayName": "Generate
UUID", "group": "function", "label": "function", "required": false, "javaType":
"String", "prefix": "${", "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "description": "Returns a UUID using the
Camel `UuidGenerator`. You can choose between `default`, `classic`, `short` and
`simple` as the type. If no type is given, the default is used. It is also
possible to use a custom `UuidG [...]
+ "variable.name": { "index": 97, "kind": "function", "displayName":
"Variable", "group": "function", "label": "function", "required": false,
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote":
"", "autowired": false, "secret": false, "description": "The variable with the
given name", "ognl": true, "suffix": "}" },
+ "variableAs(key,type)": { "index": 98, "kind": "function", "displayName":
"Variable As", "group": "function", "label": "function", "required": false,
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote":
"", "autowired": false, "secret": false, "description": "Converts the variable
to the given type (classname).", "ognl": false, "suffix": "}" },
+ "variables": { "index": 99, "kind": "function", "displayName":
"Variables", "group": "function", "label": "function", "required": false,
"javaType": "java.util.Map", "prefix": "${", "deprecated": false,
"deprecationNote": "", "autowired": false, "secret": false, "description":
"Returns all the variables from the current Exchange in a Map", "ognl": false,
"suffix": "}" },
+ "xpath(input,exp)": { "index": 100, "kind": "function", "displayName":
"XPath", "group": "function", "label": "function", "required": false,
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote":
"", "autowired": false, "secret": false, "description": "When working with XML
data, then this allows using the XPath language, for example, to extract data
from the message body (in XML format). This requires having camel-xpath JAR on
the classpath. For input (optiona [...]
}
}
diff --git
a/core/camel-core-languages/src/main/docs/modules/languages/pages/simple-language.adoc
b/core/camel-core-languages/src/main/docs/modules/languages/pages/simple-language.adoc
index 7e97509a5021..78fd54f961f4 100644
---
a/core/camel-core-languages/src/main/docs/modules/languages/pages/simple-language.adoc
+++
b/core/camel-core-languages/src/main/docs/modules/languages/pages/simple-language.adoc
@@ -177,6 +177,7 @@ NOTE: Some functions take 1 or more arguments enclosed in
parentheses, and argum
|`setHeader(name,type,exp)` | `null` | Sets a message header with the given
expression (optional converting to the given type).
|`setVariable(name,type,exp)` | `null` | Sets a variable with the given
expression (optional converting to the given type).
|`stepId` | `String` | Returns the id of the current step the `Exchange` is
being routed. Returns `null` if there are no steps.
+|`throwException(type,msg)` | `Exception` | Deliberately throws an error. Uses
`IllegalArgumentException` by default if no type is specified (use fully
qualified classname).
|`type:name.field` | `Object` | To refer to a type or field by its fully
qualified classname. For example: `type:org.apache.camel.Exchange.FILE_NAME`.
|`variable.key` | `Object` | To look up the variable with the given key.
|`variable.key._OGNL_` | `Object` | To look up the variable with the given key
and then invoke Camel _OGNL syntax_.
diff --git
a/core/camel-core-languages/src/main/java/org/apache/camel/language/csimple/CSimpleHelper.java
b/core/camel-core-languages/src/main/java/org/apache/camel/language/csimple/CSimpleHelper.java
index 3304b6d7b4a2..83e22d5695de 100644
---
a/core/camel-core-languages/src/main/java/org/apache/camel/language/csimple/CSimpleHelper.java
+++
b/core/camel-core-languages/src/main/java/org/apache/camel/language/csimple/CSimpleHelper.java
@@ -18,6 +18,7 @@ package org.apache.camel.language.csimple;
import java.io.InputStream;
import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Collection;
@@ -1247,4 +1248,20 @@ public final class CSimpleHelper {
}
}
+ public static Object throwException(Exchange exchange, String message,
Class<?> clazz) {
+ try {
+ // create a new exception to that type, and provide the message as
+ Constructor<?> constructor = clazz.getConstructor(String.class);
+ Exception cause = (Exception) constructor.newInstance(message);
+ if (cause instanceof RuntimeException re) {
+ throw re;
+ } else {
+ RuntimeException re = new RuntimeCamelException(cause);
+ throw re;
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
}
diff --git
a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleConstants.java
b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleConstants.java
index 053a01531d9b..c5d494fa31c9 100644
---
a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleConstants.java
+++
b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleConstants.java
@@ -370,6 +370,10 @@ public final class SimpleConstants {
label = "function")
public static final String THREAD_NAME = "threadName";
+ @Metadata(description = "Deliberately throws an error. Uses
IllegalArgumentException by default if no type is specified (use fully
qualified classname).",
+ javaType = "java.lang.Exception", label = "function")
+ public static final String THROW_EXCEPTION = "throwException(type,msg)";
+
@Metadata(description = "The trim function trims the message body (or
expression) by removing all leading and trailing white spaces.",
label = "function", javaType = "String", displayName = "Trim")
public static final String TRIM = "trim(exp)";
diff --git
a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleExpressionBuilder.java
b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleExpressionBuilder.java
index a32960e58050..eb82f20278f9 100644
---
a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleExpressionBuilder.java
+++
b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleExpressionBuilder.java
@@ -19,6 +19,7 @@ package org.apache.camel.language.simple;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.lang.reflect.Constructor;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.util.ArrayList;
@@ -44,6 +45,7 @@ import org.apache.camel.ExchangePropertyKey;
import org.apache.camel.Expression;
import org.apache.camel.InvalidPayloadException;
import org.apache.camel.Predicate;
+import org.apache.camel.RuntimeCamelException;
import org.apache.camel.StreamCache;
import org.apache.camel.spi.ClassResolver;
import org.apache.camel.spi.ExchangeFormatter;
@@ -744,6 +746,54 @@ public final class SimpleExpressionBuilder {
};
}
+ /**
+ * Throws an exception with the given message.
+ */
+ public static Expression throwExceptionExpression(String msg, String type)
{
+ return new ExpressionAdapter() {
+ private Class<?> clazz;
+ private Expression exp;
+
+ @Override
+ public void init(CamelContext context) {
+ if (type == null) {
+ clazz = IllegalArgumentException.class;
+ } else {
+ try {
+ clazz =
context.getClassResolver().resolveMandatoryClass(type);
+ } catch (ClassNotFoundException e) {
+ throw CamelExecutionException.wrapRuntimeException(e);
+ }
+ }
+ exp = context.resolveLanguage("simple").createExpression(msg);
+ exp.init(context);
+ }
+
+ @Override
+ public Object evaluate(Exchange exchange) {
+ try {
+ String text = exp.evaluate(exchange, String.class);
+ // create a new exception to that type, and provide the
message as
+ Constructor<?> constructor =
clazz.getConstructor(String.class);
+ Exception cause = (Exception)
constructor.newInstance(text);
+ if (cause instanceof RuntimeException re) {
+ throw re;
+ } else {
+ RuntimeException re = new RuntimeCamelException(cause);
+ throw re;
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "throwException(" + msg + ")";
+ }
+ };
+ }
+
/**
* Converts the result of the expression to the given type
*/
diff --git
a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/ast/SimpleFunctionExpression.java
b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/ast/SimpleFunctionExpression.java
index 97f70aa4c004..9baf15f9d28a 100644
---
a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/ast/SimpleFunctionExpression.java
+++
b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/ast/SimpleFunctionExpression.java
@@ -1222,6 +1222,32 @@ public class SimpleFunctionExpression extends
LiteralExpression {
return SimpleExpressionBuilder.concatExpression(exp1, exp2,
separator);
}
+ // throwException function
+ remainder = ifStartsWithReturnRemainder("throwException(", function);
+ if (remainder != null) {
+ String msg;
+ String type = null;
+ String values = StringHelper.beforeLast(remainder, ")");
+ if (values == null || ObjectHelper.isEmpty(values)) {
+ throw new SimpleParserException(
+ "Valid syntax: ${throwException(msg)} or
${throwException(type,sg)} was: " + function,
+ token.getIndex());
+ }
+ if (values.contains(",")) {
+ String[] tokens = StringQuoteHelper.splitSafeQuote(values,
',', true, true);
+ if (tokens.length > 2) {
+ throw new SimpleParserException(
+ "Valid syntax: ${throwException(msg)} or
${throwException(type,msg)} was: " + function,
+ token.getIndex());
+ }
+ msg = StringHelper.removeQuotes(tokens[0]);
+ type = StringHelper.removeQuotes(tokens[1]);
+ } else {
+ msg = StringHelper.removeQuotes(values.trim());
+ }
+ return SimpleExpressionBuilder.throwExceptionExpression(msg, type);
+ }
+
// convertTo function
remainder = ifStartsWithReturnRemainder("convertTo(", function);
if (remainder != null) {
@@ -3070,6 +3096,35 @@ public class SimpleFunctionExpression extends
LiteralExpression {
code += ";";
return code;
}
+ // throwException function
+ remainder = ifStartsWithReturnRemainder("throwException(", function);
+ if (remainder != null) {
+ String msg;
+ String type = "IllegalArgumentException";
+ String values = StringHelper.before(remainder, ")");
+ if (values == null || ObjectHelper.isEmpty(values)) {
+ throw new SimpleParserException(
+ "Valid syntax: ${throwException(msg)} or
${throwException(msg,type)} was: " + function,
+ token.getIndex());
+ }
+ if (values.contains(",")) {
+ String[] tokens = codeSplitSafe(values, ',', true, true);
+ if (tokens.length > 2) {
+ throw new SimpleParserException(
+ "Valid syntax: ${throwException(msg)} or
${throwException(msg,type)} was: " + function,
+ token.getIndex());
+ }
+ msg = tokens[0];
+ type = tokens[1];
+ } else {
+ msg = values.trim();
+ }
+ msg = StringHelper.removeLeadingAndEndingQuotes(msg);
+ msg = StringQuoteHelper.doubleQuote(msg);
+ type = appendClass(type);
+ type = type.replace('$', '.');
+ return "return throwException(exchange, " + msg + ", " + type +
");";
+ }
// uppercase function
remainder = ifStartsWithReturnRemainder("uppercase(", function);
diff --git
a/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleTest.java
b/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleTest.java
index 353aa0a33b79..1c1269c06810 100644
---
a/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleTest.java
+++
b/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleTest.java
@@ -17,6 +17,7 @@
package org.apache.camel.language.simple;
import java.io.File;
+import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.ArrayList;
@@ -70,6 +71,7 @@ import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
public class SimpleTest extends LanguageTestSupport {
@@ -3620,6 +3622,29 @@ public class SimpleTest extends LanguageTestSupport {
assertTrue(expression.evaluate(exchange, Boolean.class));
}
+ @Test
+ public void testThrowException() {
+ try {
+ Expression expression =
context.resolveLanguage("simple").createExpression("${throwException('Forced
error')}");
+ expression.evaluate(exchange, Object.class);
+ fail();
+ } catch (Exception e) {
+ assertIsInstanceOf(IllegalArgumentException.class, e.getCause());
+ assertEquals("Forced error", e.getCause().getMessage());
+ }
+
+ try {
+ Expression expression
+ = context.resolveLanguage("simple")
+ .createExpression("${throwException('Some IO
error','java.io.IOException')}");
+ expression.evaluate(exchange, Object.class);
+ fail();
+ } catch (Exception e) {
+ assertIsInstanceOf(IOException.class, e.getCause().getCause());
+ assertEquals("Some IO error",
e.getCause().getCause().getMessage());
+ }
+ }
+
@Override
protected String getLanguageName() {
return "simple";