All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.kiwiproject.jaxrs.exception.ErrorMessage Maven / Gradle / Ivy

Go to download

Kiwi is a utility library. We really like Google's Guava, and also use Apache Commons. But if they don't have something we need, and we think it is useful, this is where we put it.

There is a newer version: 4.5.2
Show newest version
package org.kiwiproject.jaxrs.exception;

import static org.apache.commons.lang3.StringUtils.isBlank;

import com.google.common.base.MoreObjects;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.kiwiproject.collect.KiwiMaps;

import javax.ws.rs.core.Response;
import java.beans.ConstructorProperties;
import java.util.Collections;
import java.util.Map;

/**
 * An error message that kiwi uses in JAX-RS related utilities. This is effectively a replacement for the
 * Dropwizard class of the same name.
 * 

* Each instance contains the HTTP status (error) code; the error message; an optional identifier to identify the * specific item causing the error (e.g. a primary key); and an optional field/property name for cases when a specific * field causes the error. */ @Getter @EqualsAndHashCode @Slf4j public class ErrorMessage { public static final String KEY_CODE = "code"; public static final String KEY_FIELD_NAME = "fieldName"; public static final String KEY_ITEM_ID = "itemId"; public static final String KEY_MESSAGE = "message"; static final String DEFAULT_MSG = "Unknown error"; static final int DEFAULT_CODE = 500; private final int code; private final String fieldName; private final String itemId; private final String message; /** * Create instance with the given message and the default status code (500). * * @param message the error message */ public ErrorMessage(String message) { this(null, DEFAULT_CODE, message, null); } /** * Create instance with the given HTTP status and message. * * @param status the HTTP response status * @param message the error message */ public ErrorMessage(Response.Status status, String message) { this(null, status.getStatusCode(), message, null); } /** * Create instance with the given HTTP status code and message. * * @param code the HTTP status code * @param message the error message */ public ErrorMessage(int code, String message) { this(null, code, message, null); } /** * Create instance with the given HTTP status code, message, and field/property name. * * @param code the HTTP status code * @param message the error message * @param fieldName the field/property name that caused this error */ public ErrorMessage(int code, String message, String fieldName) { this(null, code, message, fieldName); } /** * Create instance with the given item identifier, HTTP status code, message, and field/property name. *

* Note that only this constructor has been marked with {@link ConstructorProperties} due to an open (as * of 2020-09-02) issue in Jackson Databind. * See jackson-databind issue #1514. * * @param itemId the unique ID of the item that caused this error * @param code the HTTP status code * @param message the error message * @param fieldName the field/property name that caused this error */ @ConstructorProperties({"itemId", "code", "message", "fieldName"}) public ErrorMessage(String itemId, int code, String message, String fieldName) { this.itemId = itemId; this.code = code <= 0 ? DEFAULT_CODE : code; this.message = isBlank(message) ? DEFAULT_MSG : message; this.fieldName = fieldName; } /** * Convert this instance to a map. * * @return an unmodifiable map * @see Collections#unmodifiableMap(Map) */ public Map toMap() { // Map.of and Guava's ImmutableMap do not permit null values. // This is one way to make the map "immutable" while still allowing null values. return Collections.unmodifiableMap( KiwiMaps.newHashMap( KEY_MESSAGE, message, KEY_CODE, code, KEY_FIELD_NAME, fieldName, KEY_ITEM_ID, itemId ) ); } @Override public String toString() { return MoreObjects.toStringHelper(this) .add(KEY_CODE, code) .add(KEY_MESSAGE, message) .add(KEY_FIELD_NAME, fieldName) .add(KEY_ITEM_ID, itemId) .toString(); } /** * Build an {@link ErrorMessage} from the given map of properties, whose keys must correspond to the property * names and whose values must have the expected type. * * @param props error message properties * @return a new ErrorMessage */ public static ErrorMessage valueOf(Map props) { var messageOrDefault = (String) props.getOrDefault(KEY_MESSAGE, DEFAULT_MSG); var message = isBlank(messageOrDefault) ? DEFAULT_MSG : messageOrDefault; var itemId = (String) props.get(KEY_ITEM_ID); var fieldName = (String) props.get(KEY_FIELD_NAME); var code = DEFAULT_CODE; if (props.containsKey(KEY_CODE)) { try { code = (Integer) props.get(KEY_CODE); } catch (Exception e) { LOG.error("Invalid code in properties: {}", props, e); } } return new ErrorMessage(itemId, code, message, fieldName); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy