Respostas e tratamento de erros¶
O Snowflake Native SDK for Connectors utiliza certas respostas padrão, especialmente para procedimentos expostos e projetados para serem usados a partir da UI. Além disso, ele fornece uma maneira de garantir que as exceções sejam mapeadas para respostas válidas e registradas no EVENT TABLE
.
Respostas¶
Os procedimentos SDK, tanto de alto nível como internos, utilizam variant
de uma certa estrutura para passar informações. A exigência de tal variant
é que ele tem que conter um campo response_code
e, em alguns casos, o código de resposta é diferente do OK
, no campo message
necessário. Qualquer campo adicional pode ser incluído, mas requer tratamento personalizado. O formato de resposta de THe é:
{
"response_code": "<response code>",
"message": "<message>"
}
É recomendável usar este formato ao substituir implementações padrão de procedimentos e objetos.
Tratamento de erros¶
O Snowflake Native SDK for Connectors fornece um mecanismo padrão útil para lidar com exceções que podem ocorrer durante o tempo de execução. A classe responsável por isso é chamada ConnectorErrorHelper
e sua implementação padrão é DefaultConnectorErrorHelper
. Este recurso fornece 2 retornos de chamada personalizáveis. O primeiro, ExceptionMapper
, é responsável por envolver todos os erros inesperados no formato ConnectorException
. Esse recurso é usado principalmente para garantir que as respostas estejam em conformidade com o formato mencionado acima.
O segundo retorno de chamada, chamado ExceptionLogger
, garante que o erro seja registrado. Isso é importante porque todas as entradas de log padrão são salvas no EVENT TABLE
pela Snowflake, que auxilia na resolução de problemas com os aplicativos.
Como usar o auxiliar¶
O auxiliar expõe 2 métodos:
withExceptionWrapping(Supplier<ConnectorResponse> action)
withExceptionLogging(Supplier<T> action)
Esses métodos usam respectivamente mapper
e logger
mencionados acima. Há também uma implementação padrão de um método auxiliar que mistura essas abordagens:
default ConnectorResponse withExceptionLoggingAndWrapping(Supplier<ConnectorResponse> action) {
return withExceptionWrapping(() -> withExceptionLogging(action));
}
É recomendável usar esse encapsulamento no nível mais alto possível ao invocar um método de um handler
. Por exemplo em ConnectionConfigurationHandler é usado assim:
public static Variant setConnectionConfiguration(Session session, Variant configuration) {
var handler = ConnectionConfigurationHandler.builder(session).build();
return handler.setConnectionConfiguration(configuration).toVariant();
}
public ConnectorResponse setConnectionConfiguration(Variant configuration) {
return errorHelper.withExceptionLoggingAndWrapping(
() -> setConnectionConfigurationBody(configuration)
);
}
O SDK também expõe um construtor para personalizar esse comportamento, chamado ConnectorErrorHelperBuilder
. Este construtor permite que o desenvolvedor personalize o comportamento dos retornos de chamada mapper
e logger
. Uma vez personalizado, o novo helper
pode ser passado para as classes handler
em seus respectivos builders
. Por exemplo:
class CustomUnknownExceptionMapper implements ExceptionMapper<Exception> {
@Override
public ConnectorException map(Exception exception) {
return new CustomConnectorException(exception);
}
}
class CustomHandler {
// Path to this method needs to be specified in the PUBLIC.SET_CONNECTION_CONFIGURATION procedure using SQL
public static Variant configureConnection(Session session, Variant configuration) {
//Using builder
var errorHelper = new ConnectorErrorHelperBuilder()
.withConnectorExceptionLogger(new CustomUnknownExceptionMapper())
.build();
var handler = ConnectionConfigurationHandler.builder(session)
.withErrorHelper(errorHelper)
.build();
return handler.connectionConfiguration(configuration).toVariant();
}
}