Skip to content

Commit 8cbf3f1

Browse files
committed
Modified the error handling practices to be more descriptive and removed all general Exception handling
1 parent a9dee67 commit 8cbf3f1

File tree

1 file changed

+161
-98
lines changed
  • tools/openapi-generator-maven-plugin/src/main/java/org/openmrs/plugin

1 file changed

+161
-98
lines changed

tools/openapi-generator-maven-plugin/src/main/java/org/openmrs/plugin/OpenAPIMojo.java

Lines changed: 161 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,13 @@ public void execute() throws MojoExecutionException, MojoFailureException {
8181
} else {
8282
log.warn("Artifact file not found: " + artifact.getGroupId() + ":" + artifact.getArtifactId());
8383
}
84-
}
85-
}
84+
} }
8685

8786
log.info("ClassLoader setup complete: " + urls.size() + " URLs");
8887
return new URLClassLoader(urls.toArray(new URL[0]), Thread.currentThread().getContextClassLoader());
8988

90-
} catch (Exception e) {
91-
throw new RuntimeException("Failed to setup ClassLoader", e);
89+
} catch (java.net.MalformedURLException e) {
90+
throw new RuntimeException("Invalid URL in classpath elements: " + e.getMessage(), e);
9291
}
9392
}
9493

@@ -102,15 +101,17 @@ private void disableOpenMRSContext() {
102101
log.info(" SUCCESS: OpenMRS Context disabled successfully");
103102
log.debug(" RestUtil.contextEnabled is now false");
104103
log.debug(" Static initializers will not attempt Context access");
105-
106-
} catch (ClassNotFoundException e) {
104+
} catch (ClassNotFoundException e) {
107105
log.error(" FAILED: RestUtil class not found: " + e.getMessage());
108106
throw new RuntimeException("Cannot disable OpenMRS context", e);
109107
} catch (NoSuchMethodException e) {
110108
log.error(" FAILED: disableContext method not found: " + e.getMessage());
111109
throw new RuntimeException("Cannot disable OpenMRS context", e);
112-
} catch (Exception e) {
113-
log.error(" FAILED: Error disabling context: " + e.getMessage());
110+
} catch (IllegalAccessException e) {
111+
log.error(" FAILED: Cannot access disableContext method: " + e.getMessage());
112+
throw new RuntimeException("Cannot disable OpenMRS context", e);
113+
} catch (java.lang.reflect.InvocationTargetException e) {
114+
log.error(" FAILED: disableContext method invocation failed: " + e.getCause().getMessage());
114115
throw new RuntimeException("Cannot disable OpenMRS context", e);
115116
}
116117
}
@@ -155,16 +156,15 @@ private void testRestConstantsAccessibility() {
155156
} else {
156157
log.warn(" REPRESENTATION_FULL unexpected value: " + representationFull);
157158
}
158-
159-
log.info(" SUCCESS: RestConstants is fully accessible at build time!");
159+
log.info(" SUCCESS: RestConstants is fully accessible at build time!");
160160

161161
} catch (ClassNotFoundException e) {
162162
log.error(" FAILED: RestConstants class not found in ClassLoader");
163-
log.error("This means RestConstants is not in the classpath"); } catch (NoSuchFieldException e) {
163+
log.error("This means RestConstants is not in the classpath");
164+
} catch (NoSuchFieldException e) {
164165
log.error(" FAILED: RestConstants field not found: " + e.getMessage());
165-
} catch (Exception e) {
166-
log.error(" FAILED: RestConstants not accessible: " + e.getClass().getSimpleName() + ": " + e.getMessage());
167-
e.printStackTrace();
166+
} catch (IllegalAccessException e) {
167+
log.error(" FAILED: Cannot access RestConstants fields: " + e.getMessage());
168168
}
169169
}
170170

@@ -176,9 +176,8 @@ private Class<?> loadClass(String className) {
176176
} catch (ClassNotFoundException e) {
177177
throw new RuntimeException("Failed to load class: " + className, e);
178178
}
179-
}
180-
181-
private void testPatientResourceInstantiation(Class<?> resourceClazz) {
179+
}
180+
private void testPatientResourceInstantiation(Class<?> resourceClazz) throws MojoExecutionException {
182181
log.debug("=== Testing PatientResource Instance Creation ===");
183182

184183
try {
@@ -206,128 +205,192 @@ private void testPatientResourceInstantiation(Class<?> resourceClazz) {
206205

207206
} catch (InstantiationException e) {
208207
log.error(" FAILED: Cannot instantiate class");
209-
log.error("Reason: " + e.getMessage());
210-
208+
log.error("Reason: " + e.getMessage());
211209
} catch (IllegalAccessException e) {
212210
log.error(" FAILED: Constructor not accessible");
213211
log.error("Reason: " + e.getMessage());
214212

215-
} catch (Exception e) {
216-
log.error(" FAILED: Unexpected error during instantiation");
217-
log.error("Error type: " + e.getClass().getSimpleName());
218-
log.error("Error message: " + e.getMessage());
219-
e.printStackTrace();
220-
}
221-
}
222-
223-
private void testBasicMethodCall(Object instance) {
224-
try {
225-
log.debug("--- Testing Basic Method Calls ---");
226-
227-
String toStringResult = instance.toString();
228-
log.debug(" toString() works: " + toStringResult);
229-
230-
Class<?> instanceClass = instance.getClass();
231-
log.debug(" getClass() works: " + instanceClass.getName());
232-
233-
Method[] methods = instanceClass.getDeclaredMethods();
234-
log.debug(" Found " + methods.length + " declared methods");
213+
} catch (NoSuchMethodException e) {
214+
log.error(" FAILED: Default constructor not found");
215+
log.error("Reason: " + e.getMessage());
235216

236-
for (Method method : methods) {
237-
if (method.getName().equals("getRepresentationDescription")) {
238-
log.info(" Found getRepresentationDescription method: " + method.toString());
239-
}
217+
} catch (java.lang.reflect.InvocationTargetException e) {
218+
log.error(" FAILED: Constructor execution failed");
219+
log.error("Cause: " + e.getCause().getClass().getSimpleName() + ": " + e.getCause().getMessage());
220+
}
221+
} private void testBasicMethodCall(Object instance) {
222+
log.debug("--- Testing Basic Method Calls ---");
223+
224+
String toStringResult = instance.toString();
225+
log.debug(" toString() works: " + toStringResult);
226+
227+
Class<?> instanceClass = instance.getClass();
228+
log.debug(" getClass() works: " + instanceClass.getName());
229+
230+
Method[] methods = instanceClass.getDeclaredMethods();
231+
log.debug(" Found " + methods.length + " declared methods");
232+
233+
for (Method method : methods) {
234+
if (method.getName().equals("getRepresentationDescription")) {
235+
log.info(" Found getRepresentationDescription method: " + method.toString());
240236
}
241-
} catch (Exception e) {
242-
log.warn(" Basic method calls failed: " + e.getMessage());
243237
}
244-
}
245-
246-
private void testGetRepresentationDescription(Object instance) {
238+
}private void testGetRepresentationDescription(Object instance) throws MojoExecutionException {
239+
log.info("=== Testing getRepresentationDescription Method ===");
240+
247241
try {
248-
log.info("=== Testing getRepresentationDescription Method ===");
242+
Class<?> representationClass = loadRequiredClass("org.openmrs.module.webservices.rest.web.representation.Representation");
243+
Class<?> defaultRepClass = loadRequiredClass("org.openmrs.module.webservices.rest.web.representation.DefaultRepresentation");
244+
Class<?> fullRepClass = loadRequiredClass("org.openmrs.module.webservices.rest.web.representation.FullRepresentation");
249245

250-
//testRestConstantsInMethodContext();
251-
252-
Class<?> representationClass = classLoader.loadClass("org.openmrs.module.webservices.rest.web.representation.Representation");
253-
Class<?> defaultRepClass = classLoader.loadClass("org.openmrs.module.webservices.rest.web.representation.DefaultRepresentation");
254-
Class<?> fullRepClass = classLoader.loadClass("org.openmrs.module.webservices.rest.web.representation.FullRepresentation");
255-
256-
Object defaultRep = defaultRepClass.getDeclaredConstructor().newInstance();
257-
Object fullRep = fullRepClass.getDeclaredConstructor().newInstance();
246+
Object defaultRep = createRequiredInstance(defaultRepClass);
247+
Object fullRep = createRequiredInstance(fullRepClass);
258248

259249
Method method = instance.getClass().getMethod("getRepresentationDescription", representationClass);
260250

261-
Object defaultResult = method.invoke(instance, defaultRep);
262-
log.info(" DEFAULT result: " + defaultResult);
251+
Object defaultResult = invokeRepresentationMethod(method, instance, defaultRep, "DEFAULT");
252+
Object fullResult = invokeRepresentationMethod(method, instance, fullRep, "FULL");
263253

264-
Object fullResult = method.invoke(instance, fullRep);
265-
log.info(" FULL result: " + fullResult); if (defaultResult != null) {
266-
extractSchemaFromDescription(defaultResult, "DEFAULT");
267-
}
268-
269-
if (fullResult != null) {
270-
extractSchemaFromDescription(fullResult, "FULL");
271-
}
254+
tryExtractSchema(defaultResult, "DEFAULT");
255+
tryExtractSchema(fullResult, "FULL");
272256

273-
} catch (Exception e) {
274-
log.error("Method invocation failed: " + e.getMessage());
257+
} catch (ClassNotFoundException e) {
258+
throw new MojoExecutionException("Required OpenMRS representation classes not found in classpath. " +
259+
"Ensure OpenMRS webservices.rest module is properly included in dependencies.", e);
260+
} catch (NoSuchMethodException e) {
261+
throw new MojoExecutionException("getRepresentationDescription method not found on resource class. " +
262+
"This OpenMRS version may not be supported.", e);
263+
} catch (InstantiationException | IllegalAccessException e) {
264+
throw new MojoExecutionException("Cannot create or access OpenMRS representation instances. " +
265+
"Check OpenMRS version compatibility.", e);
275266
}
276267
}
277268

278-
private void testRestConstantsInMethodContext() {
269+
private Class<?> loadRequiredClass(String className) throws ClassNotFoundException {
270+
return classLoader.loadClass(className);
271+
}
272+
273+
private Object createRequiredInstance(Class<?> clazz) throws InstantiationException, IllegalAccessException {
279274
try {
280-
log.info("--- Verifying RestConstants in method execution context ---");
281-
Class<?> restConstants = classLoader.loadClass("org.openmrs.module.webservices.rest.web.RestConstants");
282-
283-
Object version1 = restConstants.getField("VERSION_1").get(null);
284-
log.info(" RestConstants accessible in method context: VERSION_1 = " + version1);
285-
286-
Object repDefault = restConstants.getField("REPRESENTATION_DEFAULT").get(null);
287-
Object repFull = restConstants.getField("REPRESENTATION_FULL").get(null);
288-
289-
log.info(" Representation constants accessible:");
290-
log.info(" - REPRESENTATION_DEFAULT = " + repDefault);
291-
log.info(" - REPRESENTATION_FULL = " + repFull);
292-
293-
log.info(" RestConstants should be accessible to getRepresentationDescription()");
294-
295-
} catch (Exception e) {
296-
log.error(" RestConstants not accessible in method context: " + e.getMessage());
275+
return clazz.getDeclaredConstructor().newInstance();
276+
} catch (NoSuchMethodException e) {
277+
throw new InstantiationException("No default constructor found for " + clazz.getSimpleName());
278+
} catch (java.lang.reflect.InvocationTargetException e) {
279+
throw new InstantiationException("Constructor failed: " + e.getCause().getMessage());
297280
}
298281
}
299-
300-
private void extractSchemaFromDescription(Object description, String representationType) {
282+
283+
private Object invokeRepresentationMethod(Method method, Object instance, Object representation, String type) {
284+
try {
285+
Object result = method.invoke(instance, representation);
286+
log.info("{} result: {}", type, result);
287+
return result;
288+
} catch (java.lang.reflect.InvocationTargetException e) {
289+
log.warn("Failed to invoke getRepresentationDescription for {}: {}", type, e.getCause().getMessage());
290+
if (log.isDebugEnabled()) {
291+
log.debug("Method invocation error details", e.getCause());
292+
}
293+
return null;
294+
} catch (IllegalAccessException e) {
295+
log.warn("Cannot access getRepresentationDescription method for {}: {}", type, e.getMessage());
296+
return null;
297+
}
298+
}
299+
300+
private boolean tryExtractSchema(Object description, String representationType) {
301+
if (description == null) {
302+
log.info("No {} representation to extract schema from", representationType);
303+
return false;
304+
}
305+
306+
log.info("=== Extracting Schema from {} ===", representationType);
307+
308+
boolean propertiesSuccess = tryExtractProperties(description, representationType);
309+
if (!propertiesSuccess) {
310+
log.warn("Could not extract properties for {}", representationType);
311+
}
312+
313+
boolean linksSuccess = tryExtractLinks(description, representationType);
314+
if (!linksSuccess) {
315+
log.warn("Could not extract links for {}", representationType);
316+
}
317+
318+
return propertiesSuccess || linksSuccess;
319+
320+
}
321+
322+
private boolean tryExtractProperties(Object description, String type) {
301323
try {
302-
log.info("=== Extracting Schema from " + representationType + " ===");
303-
304324
Method getPropertiesMethod = description.getClass().getMethod("getProperties");
305325
Object properties = getPropertiesMethod.invoke(description);
306326

307327
if (properties instanceof Map) {
308328
Map<?, ?> propertyMap = (Map<?, ?>) properties;
309-
log.info("Found " + propertyMap.size() + " properties:");
329+
log.info("Found {} properties:", propertyMap.size());
310330

311331
for (Map.Entry<?, ?> entry : propertyMap.entrySet()) {
312-
String propertyName = entry.getKey().toString();
332+
String propertyName = String.valueOf(entry.getKey());
313333
Object propertyValue = entry.getValue();
314-
log.info(" - " + propertyName + " -> " + propertyValue);
334+
log.info(" - {} -> {}", propertyName, propertyValue);
315335
}
336+
return true;
337+
} else {
338+
log.warn("getProperties() returned non-Map type for {}: {}", type,
339+
properties != null ? properties.getClass().getSimpleName() : "null");
340+
return false;
316341
}
317342

343+
} catch (NoSuchMethodException e) {
344+
log.warn("getProperties method not available for {} (OpenMRS version compatibility)", type);
345+
return false;
346+
} catch (IllegalAccessException e) {
347+
log.warn("Cannot access getProperties method for {}", type);
348+
return false;
349+
} catch (java.lang.reflect.InvocationTargetException e) {
350+
log.warn("getProperties method failed for {}: {}", type, e.getCause().getMessage());
351+
if (log.isDebugEnabled()) {
352+
log.debug("getProperties error details", e.getCause());
353+
}
354+
return false;
355+
} catch (ClassCastException e) {
356+
log.warn("getProperties returned unexpected type for {}: {}", type, e.getMessage());
357+
return false;
358+
}
359+
}
360+
361+
private boolean tryExtractLinks(Object description, String type) {
362+
try {
318363
Method getLinksMethod = description.getClass().getMethod("getLinks");
319364
Object links = getLinksMethod.invoke(description);
365+
320366
if (links instanceof Map) {
321367
Map<?, ?> linkMap = (Map<?, ?>) links;
322-
log.info("Found " + linkMap.size() + " links:");
368+
log.info("Found {} links:", linkMap.size());
323369

324370
for (Map.Entry<?, ?> entry : linkMap.entrySet()) {
325-
log.info(" - LINK: " + entry.getKey() + " -> " + entry.getValue());
371+
log.info(" - LINK: {} -> {}", entry.getKey(), entry.getValue());
326372
}
373+
return true;
374+
} else {
375+
log.warn("getLinks() returned non-Map type for {}: {}", type,
376+
links != null ? links.getClass().getSimpleName() : "null");
377+
return false;
327378
}
328379

329-
} catch (Exception e) {
330-
log.error("Failed to extract schema: " + e.getMessage());
380+
} catch (NoSuchMethodException e) {
381+
log.warn("getLinks method not available for {} (OpenMRS version compatibility)", type);
382+
return false;
383+
} catch (IllegalAccessException e) {
384+
log.warn("Cannot access getLinks method for {}", type);
385+
return false;
386+
} catch (java.lang.reflect.InvocationTargetException e) {
387+
log.warn("getLinks method failed for {}: {}", type, e.getCause().getMessage());
388+
if (log.isDebugEnabled()) {
389+
log.debug("getLinks error details", e.getCause());
390+
}
391+
return false; } catch (ClassCastException e) {
392+
log.warn("getLinks returned unexpected type for {}: {}", type, e.getMessage());
393+
return false;
331394
}
332395
}
333396
}

0 commit comments

Comments
 (0)