Created 12-12-2018 01:14 PM
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
Created 12-12-2018 01:14 PM
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?
Created 12-12-2018 01:14 PM
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 ?
Created 12-12-2018 03:55 PM
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.
Created 12-12-2018 05:22 PM
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