class GDAL::CPLErrorHandler

This is used to override GDAL’s built-in error handling. By default, GDAL only logs errors to STDOUT, which doesn’t allow a whole lot of flexibility. This maps GDAL’s errors to either standard Ruby exceptions or new exceptions defined in this gem. Doing so also lets ffi-gdal users rescue these exceptions, which is beneficial for obvious reasons.

Constants

CPLE_MAP

NOTE: Error codes are defined in gdal.org/doxygen/cpl__error_8h_source.html

FAIL_PROC
FALLBACK_CPLE_EXCEPTION
SUCCESS_PROC

Attributes

on_debug[RW]

@return [Proc]

on_failure[RW]

@return [Proc]

on_fatal[RW]

@return [Proc]

on_none[RW]

@return [Proc]

on_warning[RW]

@return [Proc]

Public Class Methods

handle_error() click to toggle source

@return [Proc]

# File lib/gdal/cpl_error_handler.rb, line 44
def self.handle_error
  new.handler_lambda
end
manually_handle(message) { || ... } click to toggle source

@param message [String] Exception message if the block returns something

that should cause a raise.

@raise [GDAL::Error]

# File lib/gdal/cpl_error_handler.rb, line 51
def self.manually_handle(message)
  cpl_err = yield

  case cpl_err
  when :CE_Fatal, :CE_Failure then raise GDAL::Error, message
  end
end
new() click to toggle source
# File lib/gdal/cpl_error_handler.rb, line 74
def initialize
  @on_none = SUCCESS_PROC

  @on_debug = lambda do |_, message|
    logger.debug(message)
    true
  end

  @on_warning = lambda do |_, message|
    logger.warn(message)
    true
  end

  @on_failure = FAIL_PROC
  @on_fatal = FAIL_PROC
end

Public Instance Methods

custom_handle() { || ... } click to toggle source

Use this when you want to override the default event handling. For example, you may want to return a value in the case of a :CE_Warning. To do so, you need to create a new ErrorHandler object, assign a new Proc by calling on_warning=, then call this method with your wrapped CPLErr-returning function in a block. That might look something like:

handler = GDAL::ErrorHandler.new
handler.on_warning = -> { warn 'Uh oh!'; return Array.new }
handler.custom_handle do
  FFI::GDAL.DoSomeStuff()
end

After this code gets called, error handling will return to normal.

# File lib/gdal/cpl_error_handler.rb, line 118
def custom_handle
  FFI::CPL::Error.CPLPushErrorHandler(handler_lambda)
  yield

  msg, ptr = FFI::CPL::Error.CPLGetLastErrorMsg
  ptr.autorelease = false

  r = result(FFI::CPL::Error.CPLGetLastErrorType,
             FFI::CPL::Error.CPLGetLastErrorNo,
             msg)
  FFI::CPL::Error.CPLErrorReset
  FFI::CPL::Error.CPLPopErrorHandler

  r
end
handler_lambda() click to toggle source

Looks up the error class then calls the appropriate on_ proc, thus handling various error/non-error scenarios. More info here: www.gdal.org/cpl__error_8h.html#a74d0e649d58180e621540bf73b58e4a2.

@return [Proc] A lambda that adheres to the CPL Error interface.

# File lib/gdal/cpl_error_handler.rb, line 96
def handler_lambda
  @handler_lambda ||= lambda do |error_class, error_number, message|
    r = result(error_class, error_number, message)
    FFI::CPL::Error.CPLErrorReset

    r
  end
end

Private Instance Methods

error_class_map(error_class) click to toggle source
# File lib/gdal/cpl_error_handler.rb, line 144
def error_class_map(error_class)
  {
    CE_None: @on_none,
    CE_Debug: @on_debug,
    CE_Warning: @on_warning,
    CE_Failure: @on_failure,
    CE_Fatal: @on_fatal
  }[error_class]
end
result(error_class, error_number, message) click to toggle source

@return Whatever the Proc evaluates.

# File lib/gdal/cpl_error_handler.rb, line 137
def result(error_class, error_number, message)
  error_class_map(error_class).call(
    CPLE_MAP.fetch(error_number, FALLBACK_CPLE_EXCEPTION).fetch(:exception),
    message
  )
end