error_wrap Subroutine

private pure subroutine error_wrap(self, code, message)

Wrap the current error with a higher-level context Pushes the current error into the cause chain and sets a new top-level code and message (Rust-style “caused by”)

Print order: outermost wrapper first, root cause last (like Rust).

Usage: call parse_json(data, err) if (err%has_error()) then call err%wrap(ERROR_PARSE, “failed to load config file”) return end if

Produces: ERROR_PARSE: failed to load config file Caused by: ERROR_IO: could not read file “input.json”

Limits. The top-level message is deferred-length and never truncated, but a message pushed into the cause chain has to fit a fixed MAX_CAUSE_MSG_LEN slot; anything longer keeps its head and ends with TRUNCATION_MARKER so the clipping is visible. Likewise only MAX_CAUSE_DEPTH causes are stored: the root cause is always kept and further wraps bump omitted_causes, which the traces report as “N intermediate cause(s) omitted”, so a deep chain is never silently presented as complete.

Type Bound

error_t

Arguments

Type IntentOptional Attributes Name
class(error_t), intent(inout) :: self
integer(kind=default_int), intent(in) :: code
character(len=*), intent(in) :: message

Calls

proc~~error_wrap~~CallsGraph proc~error_wrap error_t%error_wrap proc~clip_tail clip_tail proc~error_wrap->proc~clip_tail proc~error_has_error error_t%error_has_error proc~error_wrap->proc~error_has_error

Called by

proc~~error_wrap~~CalledByGraph proc~error_wrap error_t%error_wrap proc~read_char_record read_char_record proc~read_char_record->proc~error_wrap proc~read_int32_array read_int32_array proc~read_int32_array->proc~error_wrap proc~read_int64_array read_int64_array proc~read_int64_array->proc~error_wrap proc~read_real_dp_array read_real_dp_array proc~read_real_dp_array->proc~error_wrap proc~read_real_sp_array read_real_sp_array proc~read_real_sp_array->proc~error_wrap proc~write_char_record write_char_record proc~write_char_record->proc~error_wrap proc~write_int32_array write_int32_array proc~write_int32_array->proc~error_wrap proc~write_int64_array write_int64_array proc~write_int64_array->proc~error_wrap proc~write_real_dp_array write_real_dp_array proc~write_real_dp_array->proc~error_wrap proc~write_real_sp_array write_real_sp_array proc~write_real_sp_array->proc~error_wrap interface~read_array read_array interface~read_array->proc~read_char_record interface~read_array->proc~read_int32_array interface~read_array->proc~read_int64_array interface~read_array->proc~read_real_dp_array interface~read_array->proc~read_real_sp_array interface~write_array write_array interface~write_array->proc~write_char_record interface~write_array->proc~write_int32_array interface~write_array->proc~write_int64_array interface~write_array->proc~write_real_dp_array interface~write_array->proc~write_real_sp_array proc~soa_read_int32_field soa_read_int32_field proc~soa_read_int32_field->interface~read_array proc~soa_read_int64_field soa_read_int64_field proc~soa_read_int64_field->interface~read_array proc~soa_read_logical_field soa_read_logical_field proc~soa_read_logical_field->interface~read_array proc~soa_read_prologue soa_read_prologue proc~soa_read_prologue->interface~read_array proc~soa_read_real_dp_field soa_read_real_dp_field proc~soa_read_real_dp_field->interface~read_array proc~soa_read_real_sp_field soa_read_real_sp_field proc~soa_read_real_sp_field->interface~read_array proc~soa_write_int32_field soa_write_int32_field proc~soa_write_int32_field->interface~write_array proc~soa_write_int64_field soa_write_int64_field proc~soa_write_int64_field->interface~write_array proc~soa_write_logical_field soa_write_logical_field proc~soa_write_logical_field->interface~write_array proc~soa_write_prologue soa_write_prologue proc~soa_write_prologue->interface~write_array proc~soa_write_real_dp_field soa_write_real_dp_field proc~soa_write_real_dp_field->interface~write_array proc~soa_write_real_sp_field soa_write_real_sp_field proc~soa_write_real_sp_field->interface~write_array interface~soa_read_field soa_read_field interface~soa_read_field->proc~soa_read_int32_field interface~soa_read_field->proc~soa_read_int64_field interface~soa_read_field->proc~soa_read_logical_field interface~soa_read_field->proc~soa_read_real_dp_field interface~soa_read_field->proc~soa_read_real_sp_field interface~soa_write_field soa_write_field interface~soa_write_field->proc~soa_write_int32_field interface~soa_write_field->proc~soa_write_int64_field interface~soa_write_field->proc~soa_write_logical_field interface~soa_write_field->proc~soa_write_real_dp_field interface~soa_write_field->proc~soa_write_real_sp_field proc~particle_soa_deserialize particle_soa_t%particle_soa_deserialize proc~particle_soa_deserialize->proc~soa_read_prologue proc~particle_soa_deserialize->interface~soa_read_field proc~particle_soa_serialize particle_soa_t%particle_soa_serialize proc~particle_soa_serialize->proc~soa_write_prologue proc~particle_soa_serialize->interface~soa_write_field

Source Code

   pure subroutine error_wrap(self, code, message)
      !! Wrap the current error with a higher-level context
      !! Pushes the current error into the cause chain and sets a new
      !! top-level code and message (Rust-style "caused by")
      !!
      !! Print order: outermost wrapper first, root cause last (like Rust).
      !!
      !! Usage:
      !!   call parse_json(data, err)
      !!   if (err%has_error()) then
      !!      call err%wrap(ERROR_PARSE, "failed to load config file")
      !!      return
      !!   end if
      !!
      !! Produces:
      !!   ERROR_PARSE: failed to load config file
      !!     Caused by: ERROR_IO: could not read file "input.json"
      !!
      !! Limits. The top-level `message` is deferred-length and never
      !! truncated, but a message pushed into the cause chain has to fit a
      !! fixed MAX_CAUSE_MSG_LEN slot; anything longer keeps its head and
      !! ends with TRUNCATION_MARKER so the clipping is visible. Likewise
      !! only MAX_CAUSE_DEPTH causes are stored: the root cause is always
      !! kept and further wraps bump `omitted_causes`, which the traces
      !! report as "N intermediate cause(s) omitted", so a deep chain is
      !! never silently presented as complete.
      class(error_t), intent(inout) :: self
      integer(default_int), intent(in) :: code
      character(len=*), intent(in) :: message

      if (.not. self%has_error()) return

      ! Push current error into cause chain
      if (self%cause_depth < MAX_CAUSE_DEPTH) then
         self%cause_depth = self%cause_depth + 1
         self%cause_codes(self%cause_depth) = self%code
         if (allocated(self%message)) then
            self%cause_messages(self%cause_depth) = clip_tail(self%message)
         else
            self%cause_messages(self%cause_depth) = "(no message)"
         end if
      else
         ! Chain is full. The root cause matters most, so keep what is stored
         ! and record that a middle layer was dropped.
         self%omitted_causes = self%omitted_causes + 1
      end if

      ! Set new top-level error
      self%code = code
      self%message = trim(message)
   end subroutine error_wrap