Skip to content

Instantly share code, notes, and snippets.

@jiraguha
Last active November 28, 2020 18:34
Show Gist options
  • Save jiraguha/82253e2d182da2851c0fd9e2e1f974cf to your computer and use it in GitHub Desktop.
Save jiraguha/82253e2d182da2851c0fd9e2e1f974cf to your computer and use it in GitHub Desktop.
RSocket error data - URL base convention for managing errors

Intro

ERROR Frame (0x0B) is used for errors on individual requests/streams as well as connection errors and in response to SETUP frames.

Frame Contents

     0                   1                   2                   3
     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                           Stream ID                           |
    +-----------+-+-+---------------+-------------------------------+
    |Frame Type |0|0|      Flags    |
    +-----------+-+-+---------------+-------------------------------+
    |                          Error Code                           |
    +---------------------------------------------------------------+
                               Error Data
  • Frame Type: (6 bits) 0x0B
  • Error Code: (32 bits = max value 2^31-1 = 2,147,483,647) Type of Error.
    • See list of valid Error Codes below.
  • Error Data: includes Payload describing error information. Error Data SHOULD be a UTF-8 encoded string. The string MUST NOT be null terminated.

Application layer logic generating a Reactive Streams onError event will produce a Frame Type equal to APPLICATION_ERROR.

Problematic

  • Error Data UTF-8 only is the only room we have to managing application errors.
  • Error Data should be easily parsable
  • An application can issue more that one error
  • We need room for errors contextualization like resources identifiers, tracers,...

Convention Proposal

Using HTTP URL

  • It is well structured - so it is easy to parse
  • HTTP URLs are transporting successfully information for many years.
  • We have great knowledge of it - many lib exist

Several errors management

URL could be separated by ';'

Convention

  • Error Data : ERROR_URL_1;ERROR_URL_2
  • ERROR_URL : ERROR_ORIGINATION_HOST/unique_error_code/tracer_1/tracer_2?context=context_value
  • ERROR_ORIGINATION_HOST: http://port_name.protocol.route.service.namespace.env_type.env

ERROR_ORIGINATION_HOST is inspired by Kubernetes DNS. Values on the left are more specifics

Java example

import com.squareup.okhttp.HttpUrl;

class Main {
  public static void main(String[] args) {
    String erroData = "http://port_name1.protocol1.service1.namespace1.svc1.cluster1.local/unique_error_code1/trace_id1?context11=cute%20%23puppies1&context12=images1;http://port_name2.protocol2.service2.namespace2.svc2.cluster2.local/unique_error_code2/trace_id2?context12=cute%20%23puppies2&context2=images2";
    String[] splittedErrors = erroData.split(";");
    for (int i = 0, size = 2; i < size; i++) {
      System.out.println ("====================================");
      System.out.println("Parsing: " + splittedErrors[i]);
      System.out.println ("----------------Start-----------------");
       parse(splittedErrors[i]);
       System.out.println("================End====================");
    }
  }

  public static void parse(String urlLike) {
    HttpUrl url = HttpUrl.parse(urlLike);
    System.out.println("origin: "+ url.host());
    System.out.println("code: "+ url.pathSegments().get(0));
    System.out.println("tracer: "+ url.pathSegments().get(1));
    for (int i = 0, size = url.querySize(); i < size; i++) {
      System.out.println(url.queryParameterName(i) + ": " + url.queryParameterValue(i));
    }
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment