Skip to content

Commit

Permalink
Improve error handling and logging (#237)
Browse files Browse the repository at this point in the history
* Fix error handling and improve logging
* Bump parent and deps versions
  • Loading branch information
ksclarke authored Jan 27, 2025
1 parent 0a2e8f0 commit d3bcdc6
Show file tree
Hide file tree
Showing 14 changed files with 803 additions and 283 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## webrepl

A quick and dirty REPL for JPv3's IIIF Cookbook recipes.
A quick and dirty, single-threaded REPL for JPv3's IIIF Cookbook recipes.

### How to Build

Expand Down
26 changes: 21 additions & 5 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
<!-- Dependency versions -->
<microhttp.version>0.11</microhttp.version>
<jpv3.version>0.0.0-SNAPSHOT</jpv3.version>
<freelib.utils.version>5.0.7</freelib.utils.version>
<freelib.utils.version>5.0.10</freelib.utils.version>

<!-- Configuring Sonar to use the right (i.e., webrepl) branch -->
<sonar.branch.target>webrepl</sonar.branch.target>
Expand All @@ -60,6 +60,8 @@
<!-- Test dependency versions -->
<junit.version>5.11.0</junit.version>
<mockito.version>5.14.2</mockito.version>
<awaitility.version>4.2.2</awaitility.version>
<system.lambda.version>1.2.1</system.lambda.version>

<!-- Skip the requirement that none of the dependencies are snapshot versions -->
<enforcer.skip>true</enforcer.skip>
Expand Down Expand Up @@ -116,6 +118,18 @@
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.stefanbirkner</groupId>
<artifactId>system-lambda</artifactId>
<version>${system.lambda.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.awaitility</groupId>
<artifactId>awaitility</artifactId>
<version>${awaitility.version}</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down Expand Up @@ -169,7 +183,7 @@
</filters>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>info.freelibrary.iiif.webrepl.Server</mainClass>
<mainClass>info.freelibrary.iiif.webrepl.WebRepl</mainClass>
</transformer>
</transformers>
</configuration>
Expand Down Expand Up @@ -241,7 +255,8 @@
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>${jacoco.agent.arg} -javaagent:${org.mockito:mockito-core:jar}</argLine>
<argLine>${jacoco.agent.arg} -javaagent:${org.mockito:mockito-core:jar}
--add-opens java.base/java.util=ALL-UNNAMED -Xshare:off</argLine>
<environmentVariables>
<HTTP_PORT>${test.http.port}</HTTP_PORT>
</environmentVariables>
Expand All @@ -255,7 +270,8 @@
<systemPropertyVariables>
<server.port>${test.http.port}</server.port>
</systemPropertyVariables>
<argLine>--add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED</argLine>
<argLine>--add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED
-Xshare:off</argLine>
</configuration>
</plugin>

Expand Down Expand Up @@ -396,7 +412,7 @@
<parent>
<artifactId>freelib-parent</artifactId>
<groupId>info.freelibrary</groupId>
<version>12.0.0</version>
<version>12.0.3</version>
</parent>

</project>
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
/**
* A diagnostic consumer for handling rejected code snippets.
*/
public class DiagConsumer implements Consumer<Diag> {
public class DiagnosticConsumer implements Consumer<Diag> {

/** A delimiter for the end of problematic code. */
private static final String END = "]]";
Expand Down Expand Up @@ -42,7 +42,7 @@ public class DiagConsumer implements Consumer<Diag> {
*
* @param aBuffer An output buffer
*/
public DiagConsumer(final StringBuilder aBuffer) {
public DiagnosticConsumer(final StringBuilder aBuffer) {
myBuffer = aBuffer;
}

Expand Down Expand Up @@ -71,7 +71,7 @@ public void accept(final Diag aDiagnostic) {
}

// Add line numbers to what's returned
code = StringUtils.addLineNumbers(myBuffer.toString());
code = StringUtils.addLineNumbers(myBuffer.toString().trim());

// Zero out the output buffer
myBuffer.setLength(0);
Expand Down
42 changes: 42 additions & 0 deletions src/main/java/info/freelibrary/iiif/webrepl/EnvOptions.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@

package info.freelibrary.iiif.webrepl;

import java.time.Duration;

import org.microhttp.Options;

import info.freelibrary.util.Constants;
import info.freelibrary.util.Env;

/**
* The server's environmental options.
*/
public class EnvOptions {

/** The maximum request size. */
private static final int DEFAULT_MAX_REQ_SIZE = 1_024 * 1_024;

/** The default port at which the server listens. */
private static final int DEFAULT_PORT = 8888;

/** The read buffer size. */
private static final int DEFAULT_READ_BUF_SIZE = 1_024 * 64;

/** The request timeout. */
private static final long DEFAULT_REQ_TIMEOUT = 60L;

/**
* Gets the environmental options.
*
* @return The configuration options
*/
public Options getOpts() {
final int port = Env.get(Config.HTTP_PORT, DEFAULT_PORT);
final int reqSize = Env.get(Config.MAX_REQUEST_SIZE, DEFAULT_MAX_REQ_SIZE);
final int bufSize = Env.get(Config.READ_BUFFER_SIZE, DEFAULT_READ_BUF_SIZE);
final long timeout = (long) Env.get(Config.REQUEST_TIMEOUT, DEFAULT_REQ_TIMEOUT);

return Options.builder().withHost(Constants.INADDR_ANY).withPort(port).withMaxRequestSize(reqSize)
.withRequestTimeout(Duration.ofSeconds(timeout)).withReadBufferSize(bufSize).build();
}
}
93 changes: 93 additions & 0 deletions src/main/java/info/freelibrary/iiif/webrepl/Imports.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@

package info.freelibrary.iiif.webrepl;

import static info.freelibrary.util.Constants.EOL;
import static info.freelibrary.util.StringUtils.addLineNumbers;
import static info.freelibrary.util.StringUtils.indent;
import static java.util.stream.Collectors.joining;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.nio.file.Files;
import java.nio.file.Path;

import info.freelibrary.util.warnings.PMD;
import info.freelibrary.util.warnings.Sonar;

/**
* A string of imports.
*/
public class Imports {

/** A label for the display of imports in the logs. */
private static final String LABEL = "Imports:";

/** A string of imports. */
private final String myImports;

/**
* Creates a new imports string.
*
* @throws IOException If there is trouble reading from the imports file
*/
public Imports() throws IOException {
File importsFile = Path.of("/etc/jshell/imports.jsh").toFile();

// Check to see if we're running from the Maven build
if (!importsFile.exists()) {
importsFile = Path.of("src/main/docker/imports.jsh").toFile();
}

try (BufferedReader reader = Files.newBufferedReader(importsFile.toPath())) {
myImports = reader.lines().filter(line -> !line.isBlank()).collect(joining(EOL));
}
}

/**
* Gets all the imports.
*
* @return An imports string
*/
@SuppressWarnings({ Sonar.SYSTEM_OUT_ERR, PMD.SYSTEM_PRINTLN })
public String getAll() {
if (myImports.isEmpty()) {
System.err.println();
} else {
System.err.println(EOL + LABEL);
System.err.println(indent(addLineNumbers(myImports), 2));
}

return myImports;
}

/**
* Gets all the imports that are referenced in the supplied code snippet.
*
* @param aSnippet A code snippet to check for imports
* @return An imports string
* @throws IOException if there is trouble parsing the imports
*/
@SuppressWarnings({ Sonar.SYSTEM_OUT_ERR, PMD.SYSTEM_PRINTLN })
public String getReferenced(final String aSnippet) throws IOException {
final String imports;

try (BufferedReader reader = new BufferedReader(new StringReader(myImports))) {
imports = reader.lines().filter(line -> {
final String className = line.substring(line.lastIndexOf('.') + 1, line.length() - 1);
return aSnippet == null || aSnippet.contains(className);
}).collect(joining(EOL)).trim();
}

// The above gets imports for the user, the below shows the imported imports in the logs
if (imports.isEmpty()) {
System.err.println();
} else {
System.err.println(EOL + LABEL);
System.err.println(indent(addLineNumbers(imports), 2));
}

return imports;
}
}
34 changes: 34 additions & 0 deletions src/main/java/info/freelibrary/iiif/webrepl/ParsingError.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@

package info.freelibrary.iiif.webrepl;

import info.freelibrary.util.Constants;
import info.freelibrary.util.StringUtils;

/**
* A {@code WebRepl} parsing error.
*/
public class ParsingError extends Exception {

/** The message template used in constructing the exception message. */
static final String MESSAGE_TEMPLATE =
"Parsing error, but there wasn't a useful diagnostic message. Submitted source code:" + Constants.EOL +
Constants.EOL + "{}";

/** The {@code serialVersionUID} for the ParsingError class. */
private static final long serialVersionUID = 8614571124201029070L;

/**
* Creates a parsing error for the supplied source. This type of parsing error lacks any diagnostic information from
* JShell.
*
* @param aSource A source code snippet
*/
public ParsingError(final String aSource) {
super(StringUtils.format(MESSAGE_TEMPLATE, aSource));
}

@Override
public String toString() {
return getMessage();
}
}
Loading

0 comments on commit d3bcdc6

Please sign in to comment.