Last active
April 6, 2017 03:39
-
-
Save sappenin/89ee2db2d5236a52123c174161be5fc2 to your computer and use it in GitHub Desktop.
Example of InterledgerException
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.interledger.ilp.exceptions; | |
import java.time.ZonedDateTime; | |
import java.util.Collections; | |
import java.util.List; | |
import java.util.Objects; | |
import java.util.stream.Collectors; | |
import org.interledger.ilp.InterledgerAddress; | |
import org.interledger.ilp.InterledgerAddressBuilder; | |
/** | |
* Base ILP exception. | |
* | |
* RFC REF: https://github.com/interledger/rfcs/blob/master/0003-interledger-protocol/0003-interledger-protocol.md | |
*/ | |
public class InterledgerException extends RuntimeException { | |
private static final long serialVersionUID = 1L; | |
private final ErrorCode errorCode; | |
private final InterledgerAddress triggeredBy; | |
private final List<InterledgerAddress> forwardedBy; | |
private final ZonedDateTime triggeredAt; | |
/** | |
* <p>Minimal-args Constructor.</p> | |
* | |
* <p>Allows a caller to construct an instance of this class with the minimal amount of supplied | |
* information.</p> | |
* | |
* @param errorCode An instance of {@link ErrorCode}. | |
* @param triggeredBy An instance of {@link InterledgerAddress} for the entity that originally | |
* emitted the error (MAY be an address prefix if the entity that originally omitted the error is | |
* a ledger). | |
*/ | |
public InterledgerException( | |
final ErrorCode errorCode, | |
final InterledgerAddress triggeredBy | |
) { | |
this.errorCode = Objects.requireNonNull(errorCode); | |
this.triggeredBy = Objects.requireNonNull(triggeredBy); | |
this.triggeredAt = ZonedDateTime.now(); | |
this.forwardedBy = Collections.EMPTY_LIST; // immutable | |
} | |
/** | |
* <p>All-args Constructor.</p> | |
* | |
* <p>Allows a caller to construct an instance of this class by specifying all required | |
* fields.</p> | |
* | |
* @param errorCode An instance of {@link ErrorCode}. | |
* @param triggeredBy An instance of {@link InterledgerAddress} for the entity that originally | |
* emitted the error (MAY be an address prefix if the entity that originally omitted the error is | |
* a ledger). | |
* @param triggeredAt A {@link ZonedDateTime} indicating when the error was initially emitted. | |
* @param forwardedBy A {@link List} of type {@link InterledgerAddress} that contains the | |
*/ | |
public InterledgerException( | |
final ErrorCode errorCode, | |
final InterledgerAddress triggeredBy, | |
final ZonedDateTime triggeredAt, | |
final List<InterledgerAddress> forwardedBy | |
) { | |
this.errorCode = Objects.requireNonNull(errorCode); | |
this.triggeredBy = Objects.requireNonNull(triggeredBy); | |
this.triggeredAt = Objects.requireNonNull(triggeredAt); | |
// Deep-copy the incoming list to normalize the InternetAddress, and then make it immutable. | |
final List<InterledgerAddress> newList = deepCopyAndNormalize(forwardedBy); | |
this.forwardedBy = Collections.unmodifiableList(newList); | |
} | |
/** | |
* <p>All-args Constructor.</p> | |
* | |
* <p>Allows a caller to construct an instance of this class by specifying all required | |
* fields.</p> | |
* | |
* @param errorCode An instance of {@link ErrorCode}. | |
* @param triggeredBy An instance of {@link InterledgerAddress} for the entity that originally | |
* emitted the error (MAY be an address prefix if the entity that originally omitted the error is | |
* a ledger). | |
* @param triggeredAt A {@link ZonedDateTime} indicating when the error was initially emitted. | |
* @param forwardedBy A {@link List} of type {@link InterledgerAddress} that contains the | |
* addresses of ILP connectors that relayed the error message. | |
* @param data A {@link String} containing error data for debugging purposes. | |
* @param cause An instance of {@link Throwable} that caused this exception. Used for debugging. | |
*/ | |
public InterledgerException( | |
final ErrorCode errorCode, | |
final InterledgerAddress triggeredBy, | |
final ZonedDateTime triggeredAt, | |
final List<InterledgerAddress> forwardedBy, | |
final String data, | |
final Throwable cause | |
) { | |
super(data, cause); | |
this.errorCode = Objects.requireNonNull(errorCode); | |
this.triggeredBy = Objects.requireNonNull(triggeredBy); | |
this.triggeredAt = Objects.requireNonNull(triggeredAt); | |
// Deep-copy the incoming list to normalize the InternetAddress, and then make it immutable. | |
final List<InterledgerAddress> newList = deepCopyAndNormalize(forwardedBy); | |
this.forwardedBy = Collections.unmodifiableList(newList); | |
} | |
/** | |
* Construct for adding an additional forwardedBy. | |
* | |
* @param interledgerException An instance of {@link InterledgerException}. | |
* @param forwardedBy An instance of {@link InterledgerAddress} that contains an address to be | |
* added to the list of forwarded -by addresses in the supplied {@code interledgerException}. | |
*/ | |
public InterledgerException( | |
final InterledgerException interledgerException, | |
final InterledgerAddress forwardedBy | |
) { | |
super(interledgerException.getMessage(), interledgerException.getCause()); | |
this.errorCode = interledgerException.getErrorCode(); | |
this.triggeredBy = interledgerException.getTriggeredBy(); | |
this.triggeredAt = interledgerException.getTriggeredAt(); | |
// Deep-copy the incoming list to normalize the InternetAddress, and then make it immutable. | |
final List<InterledgerAddress> newList = deepCopyAndNormalize( | |
interledgerException.getForwardedBy()); | |
newList.add(forwardedBy); | |
this.forwardedBy = Collections.unmodifiableList(newList); | |
} | |
/** | |
* Deep-copy the {@link List} supplied by {@code addresses} and return a new list with normalized | |
* instances of {@link InterledgerAddress}. | |
*/ | |
private List<InterledgerAddress> deepCopyAndNormalize(final List<InterledgerAddress> addresses) { | |
return addresses.stream() | |
.map(InterledgerAddressBuilder::new) | |
.map(InterledgerAddressBuilder::build) | |
.collect(Collectors.toList()); | |
} | |
public ErrorCode getErrorCode() { | |
return errorCode; | |
} | |
public InterledgerAddress getTriggeredBy() { | |
return triggeredBy; | |
} | |
public List<InterledgerAddress> getForwardedBy() { | |
return forwardedBy; | |
} | |
public ZonedDateTime getTriggeredAt() { | |
return triggeredAt; | |
} | |
public enum ErrorCode { | |
// FINAL ERRORS | |
F00_BAD_REQUEST("F00", "BAD REQUEST"), | |
F01_INVALID_PAQUET("F01", "INVALID PAQUET"), | |
F02_UNREACHABLE("F02", "UNREACHABLE"), | |
F03_INVALID_AMOUNT("F03", "INVALID AMOUNT"), | |
F04_INSUFFICIENT_DST_AMOUNT("F04", "INSUFFICIENT DST. AMOUNT"), | |
F05_WRONG_CONDITION("F05", "WRONG CONDITION"), | |
F06_UNEXPECTED_PAYMENT("F06", "UNEXPECTED PAYMENT"), | |
F07_CANNOT_RECEIVE("F07", "CANNOT RECEIVE"), | |
F99_APPLICATION_ERROR("F99", "APPLICATION ERROR"), | |
T00_INTERNAL_ERROR("T00", "INTERNAL ERROR"), | |
T01_LEDGER_UNREACHABLE("T01", "LEDGER UNREACHABLE"), | |
T02_LEDGER_BUSY("T02", "LEDGER BUSY"), | |
T03_CONNECTOR_BUSY("T03", "CONNECTOR BUSY"), | |
T04_INSUFFICIENT_LIQUIDITY("T04", "INSUFFICIENT LIQUIDITY"), | |
T05_RATE_LIMITED("T05", "RATE LIMITED"), | |
T99_APPLICATION_ERROR("T99", "APPLICATION ERROR"), | |
R00_TRANSFER_TIMED_OUT("R00", "TRANSFER TIMED OUT"), | |
R01_INSUFFICEINT_SOURCE_AMOUNT("R01", "INSUFFICEINT SOURCE AMOUNT"), | |
R02_INSUFFICIENT_TIMEOUT("R02", "INSUFFICIENT TIMEOUT"), | |
R99_APPLICATION_ERROR("R99", "APPLICATION ERROR"); | |
private final String code; | |
private final String name; | |
ErrorCode(String code, String name) { | |
if (code == null || name == null) { | |
throw new RuntimeException("code and/or name can not be null"); | |
} | |
code = code.trim(); | |
name = name.trim(); | |
if (code.length() != 3) { | |
throw new RuntimeException("error code length must be equal to 3"); | |
} | |
char type = code.charAt(0); | |
if (type != 'F' && type != 'T' && type != 'R') { | |
throw new RuntimeException("error code must be := 'F' | 'T' | 'R'"); | |
} | |
this.code = code; | |
this.name = name; | |
} | |
@Override | |
public String toString() { | |
return this.code + "-" + this.name(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment