Fixes #1932: Better VersionChecker exception handling

ModVersionFetcher will now return a MissingVersion in case of an exception
instead of letting it propagate upwards.

Also added a generic try/catch to the VersionChecker itself, just in case
any unchecked exception might be triggered inside the thread and at least
not logged correctly.
This commit is contained in:
yueh
2015-10-05 16:10:44 +02:00
parent 56435199b7
commit 47592bcbcb
20 changed files with 577 additions and 58 deletions
@@ -22,6 +22,17 @@ package appeng.services.version;
import java.util.Scanner;
import java.util.regex.Pattern;
import javax.annotation.Nonnull;
import com.google.common.base.Preconditions;
import appeng.services.version.exceptions.InvalidBuildException;
import appeng.services.version.exceptions.InvalidChannelException;
import appeng.services.version.exceptions.InvalidRevisionException;
import appeng.services.version.exceptions.InvalidVersionException;
import appeng.services.version.exceptions.MissingSeparatorException;
import appeng.services.version.exceptions.VersionCheckerException;
/**
* can parse a version in form of rv2-beta-8 or rv2.beta.8
@@ -42,10 +53,13 @@ public final class VersionParser
*
* @return {@link Version} encoded in the raw String
*
* @throws AssertionError if raw String does not match pattern of a {@link Version}
* @throws VersionCheckerException if parsing the raw string was not successful.
*
*/
public Version parse( final String raw )
public Version parse( @Nonnull final String raw ) throws VersionCheckerException
{
Preconditions.checkNotNull( raw );
final String transformed = this.transformDelimiter( raw );
final String[] split = transformed.split( "_" );
@@ -58,10 +72,15 @@ public final class VersionParser
* @param raw raw version string containing "." or "-"
*
* @return transformed raw, where "." and "-" are replaced by "_"
*
* @throws MissingSeparatorException if not containing valid separators
*/
private String transformDelimiter( final String raw )
private String transformDelimiter( @Nonnull final String raw ) throws MissingSeparatorException
{
assert raw.contains( "." ) || raw.contains( "-" );
if( !( raw.contains( "." ) || raw.contains( "-" ) ) )
{
throw new MissingSeparatorException();
}
final String withoutDot = PATTERN_DOT.matcher( raw ).replaceAll( "_" );
final String withoutDash = PATTERN_DASH.matcher( withoutDot ).replaceAll( "_" );
@@ -77,10 +96,18 @@ public final class VersionParser
* @param splitRaw raw version split with length of 3
*
* @return {@link Version} represented by the splitRaw
*
* @throws InvalidVersionException when length not 3
* @throws InvalidRevisionException {@link VersionParser#parseRevision(String)}
* @throws InvalidChannelException {@link VersionParser#parseChannel(String)}
* @throws InvalidBuildException {@link VersionParser#parseBuild(String)}
*/
private Version parseVersion( final String[] splitRaw )
private Version parseVersion( @Nonnull final String[] splitRaw ) throws InvalidVersionException, InvalidRevisionException, InvalidChannelException, InvalidBuildException
{
assert splitRaw.length == 3;
if( splitRaw.length != 3 )
{
throw new InvalidVersionException();
}
final String rawRevision = splitRaw[0];
final String rawChannel = splitRaw[1];
@@ -99,10 +126,15 @@ public final class VersionParser
* @param rawRevision String containing the revision number
*
* @return revision number
*
* @throws InvalidRevisionException if not matching "rv" followed by a natural number.
*/
private int parseRevision( final String rawRevision )
private int parseRevision( @Nonnull final String rawRevision ) throws InvalidRevisionException
{
assert PATTERN_VALID_REVISION.matcher( rawRevision ).matches();
if( !PATTERN_VALID_REVISION.matcher( rawRevision ).matches() )
{
throw new InvalidRevisionException();
}
final Scanner scanner = new Scanner( rawRevision );
@@ -119,10 +151,15 @@ public final class VersionParser
* @param rawChannel String containing the channel
*
* @return matching {@link Channel} to the String
*
* @throws InvalidChannelException if not one of {@link Channel} values.
*/
private Channel parseChannel( final String rawChannel )
private Channel parseChannel( @Nonnull final String rawChannel ) throws InvalidChannelException
{
assert rawChannel.equalsIgnoreCase( Channel.Alpha.name() ) || rawChannel.equalsIgnoreCase( Channel.Beta.name() ) || rawChannel.equalsIgnoreCase( Channel.Stable.name() );
if( !( rawChannel.equalsIgnoreCase( Channel.Alpha.name() ) || rawChannel.equalsIgnoreCase( Channel.Beta.name() ) || rawChannel.equalsIgnoreCase( Channel.Stable.name() ) ) )
{
throw new InvalidChannelException();
}
for( final Channel channel : Channel.values() )
{
@@ -132,7 +169,7 @@ public final class VersionParser
}
}
throw new IllegalArgumentException( "Raw channel " + rawChannel + " did not contain any of the pre-programmed types." );
throw new InvalidChannelException();
}
/**
@@ -141,10 +178,15 @@ public final class VersionParser
* @param rawBuild String containing the build number
*
* @return build number
*
* @throws InvalidBuildException if not a natural number.
*/
private int parseBuild( final String rawBuild )
private int parseBuild( @Nonnull final String rawBuild ) throws InvalidBuildException
{
assert PATTERN_NATURAL.matcher( rawBuild ).matches();
if( !PATTERN_NATURAL.matcher( rawBuild ).matches() )
{
throw new InvalidBuildException();
}
final Scanner scanner = new Scanner( rawBuild );