Apache2-API

 view release on metacpan or  search on metacpan

lib/Apache2/API.pm  view on Meta::CPAN

        {
            delete( $ref->{error}->{ $_ } ) for( qw( code status message title ) );
            delete( $ref->{error} ) if( !scalar( keys( %{$ref->{error}} ) ) );
        }

        # Set the property 'error' (extension member): string problem code if empty hash/undef
        if( !exists( $ref->{error} ) ||
            !defined( $ref->{error} ) ||
            ( !ref( $ref->{error} ) && !length( $ref->{error} // '' ) ) ||
            ( ref( $ref->{error} ) eq 'HASH' && !scalar( keys( %{$ref->{error}} ) ) ) )
        {
            delete( $ref->{error} );
            if( my $t = Apache2::API::Status->status_to_type( $code, '-' ) )
            {
                # extension member for app code
                $ref->{error} = $t;
            }
        }

        # Build 'type' URL if not provided.
        unless( exists( $ref->{type} ) &&
            defined( $ref->{type} ) &&
            length( $ref->{type} // '' ) )
        {
            if( my $host = $req->http_host )
            {
                if( my $t = Apache2::API::Status->status_to_type( $code, '-' ) )
                {
                    my $scheme = $req->is_secure ? 'https' : 'http';
                    $ref->{type} = "${scheme}://${host}/problems/${t}";
                }
            }
        }

        # Flatten legacy fields that do not belong.
        # The rfc 9457 prefers the property 'detail'.
        delete( $ref->{message} ) if( exists( $ref->{message} ) );
        # The rfc 9457 prefers the property 'status'.
        delete( $ref->{code} ) if( exists( $ref->{code} ) );
    };

    # NOTE: build_legacy_error() -> private subroutine to build the legacy error payload
    my $build_legacy_error = sub
    {
        my( $ref, $code, $msg ) = @_;
        # By now, our property 'locale' has been dealt with, so we do not have to worry about it.
        # It either exists or not
        my $locale = exists( $ref->{error}->{locale} ) ? $ref->{error}->{locale} : undef;
        # We set the property 'error' to be an HASH if not set already.
        $ref->{error} = {} unless( exists( $ref->{error} ) && ref( $ref->{error} ) eq 'HASH' );

        # The property 'code' could exist, but be undefined, or even empty, so we check for that.
        unless( exists( $ref->{error}->{code} ) &&
                defined( $ref->{error}->{code} ) &&
                length( $ref->{error}->{code} ) )
        {
            $ref->{error}->{code} = $code;
        }
        $ref->{error}->{code} = int( $ref->{error}->{code} ) if( $ref->{error}->{code} =~ /^\d+$/ );

        # We try hard to get the value for the property 'message', but if $locale is undefined, it is impossible to find out the language that was used to formulate the response.
        # So, ultimately, if we cannot find any value for the property 'message', we revert to guessing the HTTP caller's preferred language, which may, or may not be aligned with the content of other parts of the JSON response. Given that, in that s...
        if( !exists( $ref->{error}->{message} ) ||
            !defined( $ref->{error}->{message} ) ||
            !length( $ref->{error}->{message} // '' ) )
        {
            if( defined( $msg ) &&
                ( !ref( $msg ) || $self->_can_overload( $msg => "''" ) ) )
            {
                $ref->{error}->{message} = "$msg";
            }
            else
            {
                foreach my $p ( qw( message detail details ) )
                {
                    if( exists( $ref->{ $p } ) &&
                        defined( $ref->{ $p } ) &&
                        length( $ref->{ $p } ) )
                    {
                        $ref->{error}->{message} = delete( $ref->{ $p } );
                        last;
                    }
                }
            }

            # Still nothing ? Get the fallback value using 'get_http_message' either using the $locale, if defined, or the HTTP caller's preferred language
            if( !$ref->{error}->{message} )
            {
                $locale = $guess_preferred_locale->( $locale ) unless( defined( $locale ) );
                my $fallback = $locale
                    ? $resp->get_http_message( $code, $locale )
                    : $resp->get_http_message( $code );
                $ref->{error}->{message} = $fallback // 'An error occurred';
            }
        }

        # Build 'type' URL if not provided
        unless( exists( $ref->{error}->{type} ) &&
            defined( $ref->{error}->{type} ) &&
            length( $ref->{error}->{type} // '' ) )
        {
            # The user has already set the 'type' property, so we use it, and move it to our 'error' hash
            if( exists( $ref->{type} ) &&
                defined( $ref->{type} ) &&
                length( $ref->{type} ) )
            {
                $ref->{error}->{type} = delete( $ref->{type} );
            }
            elsif( my $host = $req->http_host )
            {
                if( my $t = Apache2::API::Status->status_to_type( $code ) )
                {
                    (my $slug = $t) =~ tr/_/-/;
                    my $scheme = $req->is_secure ? 'https' : 'http';
                    $ref->{error}->{type} = "${scheme}://${host}/problems/${slug}";
                }
            }
            elsif( my $t = Apache2::API::Status->status_to_type( $code ) )
            {
                $ref->{error}->{type} = $t;
            }



( run in 0.904 second using v1.01-cache-2.11-cpan-140bd7fdf52 )