Skip to content

Commit

Permalink
Merge pull request #24 from Drednote/fix/scenario
Browse files Browse the repository at this point in the history
[FIX]: fix scenario event handling and add docs
  • Loading branch information
Drednote authored Nov 23, 2024
2 parents cbbcec4 + c5aa330 commit 9041474
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 17 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,9 @@ handling. Here are some important rules to keep in mind:
process
- Methods marked with `@TelegramExceptionHandler` annotation can accept a specific set of inputs
parameters as defined in the [Argument resolving](#argument-resolving) section
- Methods marked with `@TelegramExceptionHandler` annotation can return any object, as a result. The
response processing mechanism is detailed in the [Response Processing](#response-processing)
section

### Argument resolving

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package io.github.drednote.telegram.exception.type;

/**
* Exception that throws during scenario processing.
*/
public class ScenarioException extends TelegramException {

public ScenarioException(String message) {
super(message);
}

public ScenarioException(String message, Throwable cause) {
super(message, cause);
}

public ScenarioException(Throwable cause) {
super(cause);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ public interface Scenario<S> {
* Sends an event to the scenario.
*
* @param request the update request to be processed
* @return true if the event was successfully handled, false otherwise
* @return the result of event handling.
*/
boolean sendEvent(UpdateRequest request);
ScenarioEventResult sendEvent(UpdateRequest request);

/**
* Checks if the scenario matches the specified update request.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package io.github.drednote.telegram.handler.scenario;

import io.github.drednote.telegram.core.request.UpdateRequest;
import org.springframework.lang.Nullable;

/**
* Result of a handling event.
*
* @author Ivan Galushko
* @see Scenario#sendEvent(UpdateRequest)
*/
public interface ScenarioEventResult {

/**
* @return true if the event was successfully handled, false otherwise.
*/
boolean success();

/**
* @return exception that thrown during scenario processing, null otherwise.
*/
@Nullable
Exception exception();

/**
* Default realization of {@code ScenarioEventResult}
*/
record SimpleScenarioEventResult(
boolean success, @Nullable Exception exception
) implements ScenarioEventResult {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,19 @@
public class ScenarioUpdateHandler implements UpdateHandler {

@Override
public void onUpdate(UpdateRequest request) {
public void onUpdate(UpdateRequest request) throws Exception {
Scenario<?> scenario = request.getScenario();
if (scenario != null) {
ScenarioIdResolver idResolver = scenario.getAccessor().getIdResolver();
final String id = scenario.getId();
boolean sendEvent = scenario.sendEvent(request);
if (sendEvent) {
ScenarioEventResult eventResult = scenario.sendEvent(request);
if (eventResult.success()) {
String id = scenario.getId();
ScenarioIdResolver idResolver = scenario.getAccessor().getIdResolver();
idResolver.saveNewId(request, id);
} else {
Exception exception = eventResult.exception();
if (exception != null) {
throw exception;
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import io.github.drednote.telegram.core.request.UpdateRequest;
import io.github.drednote.telegram.core.request.UpdateRequestMapping;
import io.github.drednote.telegram.core.request.UpdateRequestMappingAccessor;
import io.github.drednote.telegram.exception.type.ScenarioException;
import io.github.drednote.telegram.handler.scenario.ScenarioEventResult.SimpleScenarioEventResult;
import io.github.drednote.telegram.handler.scenario.data.SimpleState;
import io.github.drednote.telegram.handler.scenario.data.State;
import io.github.drednote.telegram.handler.scenario.data.Transition;
Expand Down Expand Up @@ -37,14 +39,16 @@ public SimpleScenario(
}

@Override
public boolean sendEvent(UpdateRequest request) {
public ScenarioEventResult sendEvent(UpdateRequest request) {
synchronized (this) {
if (isTerminated()) {
return false;
return new SimpleScenarioEventResult(false,
new ScenarioException("Scenario has been terminated"));
}
Optional<Transition<S>> optionalSTransition = findTransition(request);
if (optionalSTransition.isEmpty()) {
return false;
return new SimpleScenarioEventResult(false,
new ScenarioException("Transition not found"));
}
Transition<S> transition = optionalSTransition.get();
State<S> target = transition.getTarget();
Expand All @@ -54,12 +58,12 @@ public boolean sendEvent(UpdateRequest request) {
Object response = target.execute(context);
ResponseSetter.setResponse(request, response);
} catch (Exception e) {
log.error("Unhandled exception", e);
return false;
return new SimpleScenarioEventResult(false,
new ScenarioException("During scenario event unhandled exception happened", e));
}

this.state = target;
return true;
return new SimpleScenarioEventResult(true, null);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,9 @@ void shouldCorrectChooseNextStateIfPersisterEmpty() {
Scenario<String> scenario = factory.create(id);
persister.restore(scenario, id);

boolean sendEvent = scenario.sendEvent(updateRequest);
ScenarioEventResult sendEvent = scenario.sendEvent(updateRequest);

assertThat(sendEvent).isTrue();
assertThat(sendEvent.success()).isTrue();
assertThat(scenario.getState().getId()).isEqualTo("3");
}

Expand All @@ -85,9 +85,9 @@ void shouldCorrectChooseNextStateIfPersisterNotEmpty() throws IOException {
Scenario<String> scenario = factory.create(id);
persister.restore(scenario, id);

boolean sendEvent = scenario.sendEvent(updateRequest);
ScenarioEventResult sendEvent = scenario.sendEvent(updateRequest);

assertThat(sendEvent).isTrue();
assertThat(sendEvent.success()).isTrue();
assertThat(scenario.getState().getId()).isEqualTo("4");
}

Expand Down

0 comments on commit 9041474

Please sign in to comment.