Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Include exception cause in error output #16

Merged
merged 4 commits into from
Jul 14, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 9 additions & 29 deletions src/main/php/xp/lambda/AwsRunner.class.php
Original file line number Diff line number Diff line change
@@ -49,50 +49,31 @@ private static function endpoint($environment, $path) {
return $c;
}

/**
* Reads a value from the given input stream
*
* @param io.streams.InputStream
* @return var
*/
private static function read($in) {
return Json::read(new StreamInput($in));
}

/**
* Marshals a value
*
* @param var $value
* @return string
*/
private static function value($value) {
return Json::of($value);
}

/**
* Marshals an error according to the AWS specification.
*
* @param Throwable $e
* @return string
* @return [:var]
*/
private static function error($e) {
public static function error($e) {
$error= ['errorMessage' => $e->getMessage(), 'errorType' => nameof($e), 'stackTrace' => []];

$t= XPException::wrap($e);
do {
$error['stackTrace'][]= $t->compoundMessage();
foreach ($t->getStackTrace() as $e) {
$error['stackTrace'][]= sprintf(
'%s::%s(...) (line %d of %s)%s',
strtr($e->class, '\\', '.') ?: '<main>',
$e->method,
$e->line,
basename($e->file),
$e->file ? basename($e->file) : '',
$e->message ? ' - '.$e->message : ''
);
}
} while ($t= $t->getCause());

return Json::of($error);
return $error;
}

/**
@@ -109,7 +90,7 @@ public static function main($args) {
$lambda= self::handler($environment, Console::$out)->lambda();
} catch (Throwable $t) {
self::endpoint($environment, 'init/error')->post(
new RequestData(self::error($t)),
new RequestData(Json::of(self::error($t))),
['Content-Type' => 'application/json']
);
return 1;
@@ -126,17 +107,16 @@ public static function main($args) {

$context= new Context($r->headers(), $environment);
try {
$event= 0 === $context->payloadLength ? null : self::read($r->in());

$event= 0 === $context->payloadLength ? null : Json::read(new StreamInput($r->in()));
$type= 'response';
$response= self::value($lambda($event, $context));
$response= $lambda($event, $context);
} catch (Throwable $t) {
$type= 'error';
$response= self::error($t);
}

self::endpoint($environment, "invocation/{$context->awsRequestId}/{$type}")->post(
new RequestData($response),
new RequestData(Json::of($response)),
['Content-Type' => 'application/json']
);
} while (true);
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php namespace com\amazon\aws\lambda\unittest;

use lang\{IllegalArgumentException, IllegalStateException};
use unittest\{Assert, Test};
use xp\lambda\AwsRunner;

class ExceptionTest {

#[Test]
public function includes_errorMessage() {
Assert::equals(
'Test',
AwsRunner::error(new IllegalArgumentException('Test'))['errorMessage']
);
}

#[Test]
public function includes_errorType() {
Assert::equals(
'lang.IllegalArgumentException',
AwsRunner::error(new IllegalArgumentException('Test'))['errorType']
);
}

#[Test]
public function includes_stackTrace() {
Assert::true(in_array(
'Exception lang.IllegalArgumentException (Test)',
AwsRunner::error(new IllegalArgumentException('Test'))['stackTrace']
));
}

#[Test]
public function includes_cause() {
Assert::true(in_array(
'Exception lang.IllegalStateException (Cause)',
AwsRunner::error(new IllegalArgumentException('Test', new IllegalStateException('Cause')))['stackTrace']
));
}
}