Skip to content

Validation & Errors

Steppy validates type compatibility when building flows and captures failures during execution.

Result types

Flow invocation returns a Result indicating success, failure or abort.

class AppendAStep implements Step<None, String, String> {
    @Override
    public String invoke(Context<None> ctx, String in) {
        return in + "A";
    }
}

class FailStep implements Step<None, String, String> {
    @Override
    public String invoke(Context<None> ctx, String in) throws ExecutionException {
        throw new ExecutionException("Fail");
    }
}

StaticStepRepository.register(AppendAStep.class, FailStep.class);

var flow = StaticFlowBuilderFactory
    .builder(String.class, String.class)
    .append(AppendAStep.class)
    .append(FailStep.class)
    .build();

Result<String> result = flow.invoke("");
result.getType();                 // FAILED
result.getException().getMessage(); // "Fail"

Aborting a flow

class AbortStep implements Step<None, String, String> {
    @Override
    public String invoke(Context<None> ctx, String in) {
        ctx.abort();
        return null;
    }
}

Calling abort() stops the flow and returns a result of type ABORTED.

Type validation

The builder checks that the input and output types of all steps line up. Mismatches throw a ValidationException.

var builder = StaticFlowBuilderFactory.builder(String.class, Integer.class);
builder.append(AppendAStep.class).build(); // throws ValidationException

Generic types

Steps may declare parameterized types. Steppy keeps that information for validation.

class SumOptional implements Step<Optional<Integer>, Optional<Integer>, Optional<Integer>> {
    @Override
    public Optional<Integer> invoke(Context<Optional<Integer>> ctx,
                                     Optional<Integer> in) {
        return Optional.of(in.orElse(0) + ctx.getConfiguration().orElse(0));
    }
}

var flow = StaticFlowBuilderFactory.builder(Optional.class, Optional.class)
    .append(SumOptional.class).build();
flow.invoke(Configurations.of(Optional.of(1)), Optional.of(2)).getResult(); // Optional[3]