ThriftDocServicePlugin implements DocServicePlugin { @VisibleForTesting static ExceptionInfo newExceptionInfo(Class<? extends TException> exceptionClass) { requireNonNull(exceptionClass, "exceptionClass"); final String name = exceptionClass.getName(); List<FieldInfo> fields; try { @SuppressWarnings("unchecked") final Map<?, FieldMetaData> metaDataMap = (Map<?, FieldMetaData>) exceptionClass.getDeclaredField("metaDataMap").get(null); fields = metaDataMap.values().stream() .map(fieldMetaData -> newFieldInfo(exceptionClass, fieldMetaData)) .collect(toImmutableList()); } catch (IllegalAccessException e) { throw new AssertionError("will not happen", e); } catch (NoSuchFieldException ignored) { fields = Collections.emptyList(); } return new ExceptionInfo(name, fields); }  @Override String name(); @Override Set<Class<? extends Service<?, ?>>> supportedServiceTypes(); @Override ServiceSpecification generateSpecification(Set<ServiceConfig> serviceConfigs,
                                                      DocServiceFilter filter); @VisibleForTesting ServiceSpecification generate(List<Entry> entries, DocServiceFilter filter); @Override Map<String, String> loadDocStrings(Set<ServiceConfig> serviceConfigs); @Override Set<Class<?>> supportedExampleRequestTypes(); @Override String guessServiceName(Object exampleRequest); @Override String guessServiceMethodName(Object exampleRequest); @Override String serializeExampleRequest(String serviceName, String methodName,
                                          Object exampleRequest);  }
@Test void testNewExceptionInfo() { final ExceptionInfo exception = newExceptionInfo(FooServiceException.class); assertThat(exception).isEqualTo(new ExceptionInfo( FooServiceException.class.getName(), ImmutableList.of(newFieldInfo( FooServiceException.class, new FieldMetaData("stringVal", TFieldRequirementType.DEFAULT, new FieldValueMetaData(TType.STRING, false)))))); }