[pve-devel] r5001 - pve-common/trunk

svn-commits at proxmox.com svn-commits at proxmox.com
Mon Aug 16 11:02:12 CEST 2010


Author: dietmar
Date: 2010-08-16 09:02:12 +0000 (Mon, 16 Aug 2010)
New Revision: 5001

Modified:
   pve-common/trunk/ChangeLog
   pve-common/trunk/Exception.pm
   pve-common/trunk/JSONSchema.pm
   pve-common/trunk/RESTHandler.pm
Log:
	* RESTHandler.pm (handle): remove ugly $resp parameter - we can
	now use the new Expection object to return better error info.

	* JSONSchema.pm (validate): use new PVE::Exception::raise() in validate()

	* Exception.pm (new): finalize implementation



Modified: pve-common/trunk/ChangeLog
===================================================================
--- pve-common/trunk/ChangeLog	2010-08-13 09:14:51 UTC (rev 5000)
+++ pve-common/trunk/ChangeLog	2010-08-16 09:02:12 UTC (rev 5001)
@@ -1,3 +1,12 @@
+2010-08-16  Proxmox Support Team  <support at proxmox.com>
+
+	* RESTHandler.pm (handle): remove ugly $resp parameter - we can
+	now use the new Expection object to return better error info.
+
+	* JSONSchema.pm (validate): use new PVE::Exception::raise() in validate()
+
+	* Exception.pm (new): finalize implementation
+
 2010-08-13  Proxmox Support Team  <support at proxmox.com>
 
 	* JSONSchema.pm (register_format): implement a way to register

Modified: pve-common/trunk/Exception.pm
===================================================================
--- pve-common/trunk/Exception.pm	2010-08-13 09:14:51 UTC (rev 5000)
+++ pve-common/trunk/Exception.pm	2010-08-16 09:02:12 UTC (rev 5001)
@@ -2,13 +2,14 @@
 
 # a way to add more information to exceptions (see man perlfunc (die))
 # use PVE::Exception qw(raise);
-# raise (400, "my error message", param1 => 1, param2 => 2);
+# raise ("my error message", code => 400, errors => { param1 => "err1", ...} );
 
 package PVE::Exception;
 
 use strict;
 use vars qw(@ISA @EXPORT_OK);
 require Exporter;
+use Storable qw(dclone);       
 
 @ISA = qw(Exporter);
 
@@ -17,18 +18,18 @@
 @EXPORT_OK = qw(raise);
 
 sub new {
-    my ($class, $code, $msg, %params) = @_;
+    my ($class, $msg, %param) = @_;
 
     $class = ref($class) || $class;
 
     my $self = {
-	code => $code,
 	msg => $msg,
     };
 
-    foreach my $p (keys %params) {
+    foreach my $p (keys %param) {
 	next if defined($self->{$p}); 
-	$self->{$p} = $params{$p};
+	my $v = $param{$p};
+	$self->{$p} = ref($v) ? dclone($v) : $v;
     }
 
     return bless $self;
@@ -36,10 +37,10 @@
 
 sub raise {
 
+    my $exc = PVE::Exception->new(@_);
+    
     my ($pkg, $filename, $line) = caller;
 
-    my $exc = PVE::Exception->new(@_);
-    
     $exc->{filename} = $filename;
     $exc->{line} = $line;
 
@@ -49,7 +50,7 @@
 sub stringify {
     my $self = shift;
     
-    my $msg = $self->{msg};
+    my $msg = $self->{code} ? "$self->{code} $self->{msg}" : $self->{msg};
 
     if ($msg !~ m/\n$/) {
 
@@ -60,6 +61,12 @@
 	$msg .= "\n";
     }
 
+    if ($self->{errors}) {
+	foreach my $e (keys %{$self->{errors}}) {
+	    $msg .= "$e: $self->{errors}->{$e}\n";
+	}
+    }
+
     if ($self->{propagate}) {
 	foreach my $pi (@{$self->{propagate}}) {
 	    $msg .= "\t...propagated at $pi->[0] line $pi->[1]\n";

Modified: pve-common/trunk/JSONSchema.pm
===================================================================
--- pve-common/trunk/JSONSchema.pm	2010-08-13 09:14:51 UTC (rev 5000)
+++ pve-common/trunk/JSONSchema.pm	2010-08-16 09:02:12 UTC (rev 5001)
@@ -6,6 +6,8 @@
 use Getopt::Long;
 use Devel::Cycle -quiet; # fixme: remove?
 use PVE::Tools qw(split_list);
+use PVE::Exception qw(raise);
+use HTTP::Status qw(:constants);
 use Data::Dumper; # fixme: remove
 
 # Note: This class implements something similar to JSON schema, but it is not 100% complete. 
@@ -347,9 +349,10 @@
 }
 
 sub validate {
-    my ($instance, $schema) = @_;
+    my ($instance, $schema, $errmsg) = @_;
 
     my $errors = {};
+    $errmsg = "Paramter verification failed.\n" if !$errmsg;
 
     # fixme: cycle detection is only needed for debugging, I guess
     # we can disable that in the final release
@@ -362,7 +365,11 @@
 	check_prop($instance, $schema, '', $errors);
     }
     
-    return {valid => !scalar(%$errors), errors => $errors};
+    if (scalar(%$errors)) {
+	raise $errmsg, code => HTTP_BAD_REQUEST, errors => $errors;
+    }
+
+    return 1;
 }
 
 my $schema_valid_types = ["string", "object", "coderef", "array", "boolean", "number", "integer", "null", "any"];
@@ -585,32 +592,18 @@
 };
 
 sub validate_schema {
-    my ($schema, $pre) = @_; 
+    my ($schema) = @_; 
 
-    $pre = '' if !$pre;
-
-    my $res = validate($schema, $default_schema);
-    if (!$res->{valid}) {
-	foreach my $e (keys %{$res->{errors}}) {
-	    warn "$pre$e: $res->{errors}->{$e}\n";
-	}
-	die "internal error - unable to verify schema";
-    }
-
-    return 1;
+    my $errmsg = "internal error - unable to verify schema\n";
+    validate($schema, $default_schema, $errmsg);
 }
 
 sub validate_method_info {
     my $info = shift;
 
-    my $res = validate($info, $method_schema);
-    if (!$res->{valid}) {
-	foreach my $e (keys %{$res->{errors}}) {
-	    warn "$e: $res->{errors}->{$e}\n";
-	}
-	die "internal error - unable to verify method info";
-    }
-
+    my $errmsg = "internal error - unable to verify method info\n";
+    validate($info, $method_schema, $errmsg);
+ 
     validate_schema($info->{parameters}) if $info->{parameters};
     validate_schema($info->{returns}) if $info->{returns};
 }

Modified: pve-common/trunk/RESTHandler.pm
===================================================================
--- pve-common/trunk/RESTHandler.pm	2010-08-13 09:14:51 UTC (rev 5000)
+++ pve-common/trunk/RESTHandler.pm	2010-08-16 09:02:12 UTC (rev 5001)
@@ -3,6 +3,7 @@
 use strict;
 use warnings;
 use PVE::SafeSyslog;
+use PVE::Exception;
 use PVE::JSONSchema;
 use HTTP::Status qw(:constants :is status_message);
 
@@ -62,23 +63,7 @@
 	params => $param || {},
     };
 
-    my $res = {};
-    $res->{status} = $self->handle($info, $conn, $res);
- 
-    my $status = $res->{status};
-    if (!is_success($status)) {
-	my $msg = $res->{message} || status_message($status);
-	chomp $msg;
-	$msg .= "\n";
-	if ($res->{errors}) {
-	    foreach my $e (keys %{$res->{errors}}) {
-		$msg .= "$e: $res->{errors}->{$e}\n";
-	    }
-	}
-	die $msg;
-    }
-
-    return $res->{data};
+    return $self->handle($info, $conn);
 };
 
 sub AUTOLOAD {
@@ -196,56 +181,33 @@
 }
 
 sub handle {
-    my ($self, $info, $conn, $resp) = @_;
+    my ($self, $info, $conn) = @_;
 
+    #$resp->{message} = "Method lookup failed ('$info->{name}')";
+    #$resp->{status} = HTTP_INTERNAL_SERVER_ERROR;
+    #$resp->{errors} = $res->{errors},
+    #$resp->{data} = $result;
+
     my $func = $info->{code};
 
     if (!($info->{name} && $func)) {
-	$resp->{message} = "Method lookup failed ('$info->{name}')";
-	$resp->{status} = HTTP_INTERNAL_SERVER_ERROR;
-	return $resp->{status};
+	raise("Method lookup failed ('$info->{name}')\n",
+	      code => HTTP_INTERNAL_SERVER_ERROR);
     }
 
     if (my $schema = $info->{parameters}) {
 	# warn "validate ". Dumper($conn->{params}) . "\n" . Dumper($schema);
-	my $res = PVE::JSONSchema::validate($conn->{params}, $schema);
-	if (!$res->{valid}) {
-	    $resp->{status} = HTTP_BAD_REQUEST;
-	    $resp->{message} = "Parameter verification failed";
-	    $resp->{errors} = $res->{errors},
-	    return $resp->{status};
-	}
+	PVE::JSONSchema::validate($conn->{params}, $schema);
     }
 
-    eval{
-	my $result = &$func($conn, $resp, $conn->{params});
-	$resp->{status} = HTTP_OK if !$resp->{status};
-	$resp->{data} = $result;
-    };
-    my $err = $@;
+    my $result = &$func($conn, $conn->{params}); 
 
-    if ($err) {
-	$resp->{message} = $err;
-
-	$resp->{status} = HTTP_BAD_REQUEST
-	    if !($resp->{status} && is_error($resp->{status}));
-    }
-
     # fixme: this is only to be safe
-    if (!$err && (my $schema = $info->{returns})) {
-
-	my $res = PVE::JSONSchema::validate($resp->{data}, $schema);
-	if (!$res->{valid}) {
-
-	    $resp->{message} = "Result verification vailed";
-	    $resp->{status} = HTTP_INTERNAL_SERVER_ERROR;
-	    $resp->{errors} = $res->{errors};
-
-	    return $resp->{status};
-	} 
+    if (my $schema = $info->{returns}) {
+	PVE::JSONSchema::validate($result, $schema, "Result verification vailed\n");
     }
 
-    return $resp->{status};
+    return $result;
 }
 
 sub cli_handler {



More information about the pve-devel mailing list