Support Questions
Find answers, ask questions, and share your expertise

UndeclaredThrowableException in InvokeScriptedProcessor

Dears

I managed to create simple InvokeScriptedProcessor.. Code is working fine. However, if I made code error intentionally I get the below error, UndeclaredThrowableException.

2018-12-11 12:30:59,400 WARN [Timer-Driven Process Thread-7] o.a.n.c.t.ContinuallyRunProcessorTask Administratively Yielding InvokeScriptedProcessor[id=115d1249-1fba-1c84-7af8-8918fa3e1ecd] due to uncaught Exception: java.lang.reflect.UndeclaredThrowableException 2018-12-11 12:30:59,400 WARN [Timer-Driven Process Thread-7] o.a.n.c.t.ContinuallyRunProcessorTask java.lang.reflect.UndeclaredThrowableException: null

Code:

import java.nio.charset.StandardCharsets
import java.io.IOException
class TESTSCRIPT implements Processor {
def REL_SUCCESS = new Relationship.Builder()
.name("success")
.description("The flowfile with the specified query results was successfully transferred.")
.build();
def REL_FAILURE = new Relationship.Builder()
.name("failure")
.description("An error occured while running the specified query.")
.build();
def REL_BACK = new Relationship.Builder()
.name("backup")
.description("Backup files.")
.build();

def PORT_NUMBER = new PropertyDescriptor.Builder()
.name('Port number')
.description('Port number')
.required(true)
.expressionLanguageSupported(true)
.addValidator(StandardValidators.PORT_VALIDATOR)
.build()

def FILENAME = new PropertyDescriptor.Builder()
.name('File Name')
.description('Sets the filename attribute of the flowfile (do not include the extension).')
.required(true)
.expressionLanguageSupported(true)
.addValidator(Validator.VALID)
.build()
def ComponentLog log
@Override
void initialize(ProcessorInitializationContext context) {
log = context.getLogger()
}
@Override
Set<Relationship> getRelationships() {
return [REL_SUCCESS, REL_FAILURE, REL_BACK] as Set
}
@Override
void onTrigger(ProcessContext context, ProcessSessionFactory sessionFactory) throws ProcessException {
///// Code
def session = sessionFactory.createSession()
def flowFile = session.get()
if(!flowFile) return
def FILENAME = context.getProperty(FILENAME).value
def PORT_NUMBER = context.getProperty(PORT_NUMBER).value

  flowFile = session.write(flowFile, {inputStream, outputStream ->
inputStream.eachLine { line ->
def a = line.split("\\|", -1)
outputStream.write("${PORT_NUMBER}: Test\n".toString().getBytes(StandardCharsets.UTF_8))
}
} as StreamCallback)
                    flowFile = session.putAttribute(flowFile, "filename", FILENAME)         
try {

FlowFile flowFilec = session.clone(flowFile);
//log.error("ExecuteScript: transfer file")

session.transfer(flowFile, REL_SUCCESS)
session.transfer(flowFilec, REL_BACK)
session.commit()
}
catch (e) {
log.error('Scripting error: ', e)
session.transfer(flowFile, REL_FAILURE)
//session.rollback(true)
session.commit()
} 
}
////////////
@Override
Collection<ValidationResult> validate(ValidationContext context) { return null }
@Override
PropertyDescriptor getPropertyDescriptor(String name) {
switch(name) {
case 'File Name': return FILENAME
case 'SMPP Port number': return PORT_NUMBER
default: return null         
}
}
@Override
void onPropertyModified(PropertyDescriptor descriptor, String oldValue, String newValue) { }
@Override
List<PropertyDescriptor> getPropertyDescriptors() {
return [FILENAME, PORT_NUMBER] as List
}
@Override
String getIdentifier() { return 'TESTSCRIPT-InvokeScriptedProcessor' }
}
processor = new TESTSCRIPT()
Not sure why this Exception is generated, how can I handle it? so I get only the errors that are related to the code problem
4 REPLIES 4

Re: UndeclaredThrowableException in InvokeScriptedProcessor

Super Guru

The code is hard to read as-is (many lines are treated like comments when I assume they are not). Could you format the code block above so it looks like the script you're running? Also can you share more of the stack trace from the exception?

Re: UndeclaredThrowableException in InvokeScriptedProcessor

Thanks @Matt Burgess

I updated the code, I added "flowFilec" which is not declared. Thus will generate the UndeclaredThrowableException. I dont know why or how to handle this exception ?

Re: UndeclaredThrowableException in InvokeScriptedProcessor

Super Guru

Your Processor implementation is responsible for handling any errors/exceptions that may occur inside the script; otherwise the UndeclaredThrowableException is propagated up to InvokeScriptedProcessor, which then throws a ProcessException.

You can put a try/catch clause around your code, and in the catch you can handle the error however you like. Sometimes if there are incoming flow file(s) you would route them to failure (after perhaps penalizing them) or retry (possibly using the context to yield the processor), or to wrap the exception in a ProcessException, which is handled more cleanly by InvokeScriptedProcessor.

Re: UndeclaredThrowableException in InvokeScriptedProcessor

Thank you Matt, I have used try/catch but the strange thing is that when I changed flowFilec to flowFile, in the session.transfer(flowFilec, REL_BACK), it generates an error but doesn't trigger the catch clause